// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package profiles

import (
	"encoding/xml"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"sync"
	"time"

	"v.io/jiri"
	"v.io/jiri/runutil"
)

const (
	defaultFileMode = os.FileMode(0644)
)

type Version int

const (
	// Original, old-style profiles without a version #
	Original Version = 0
	// First version of new-style profiles.
	V2 Version = 2
	// V3 added support for recording the options that were used to install profiles.
	V3 Version = 3
	// V4 adds support for relative path names in profiles and environment variable.
	V4 Version = 4
	// V5 adds support for multiple profile installers.
	V5 Version = 5
)

type profilesSchema struct {
	XMLName xml.Name `xml:"profiles"`
	// The Version of the schema used for this file.
	Version Version `xml:"version,attr,omitempty"`
	// The name of the installer that created the profiles in this file.
	Installer string           `xml:"installer,attr,omitempty"`
	Profiles  []*profileSchema `xml:"profile"`
}

type profileSchema struct {
	XMLName xml.Name        `xml:"profile"`
	Name    string          `xml:"name,attr"`
	Root    string          `xml:"root,attr"`
	Targets []*targetSchema `xml:"target"`
}

type targetSchema struct {
	XMLName         xml.Name    `xml:"target"`
	Arch            string      `xml:"arch,attr"`
	OS              string      `xml:"os,attr"`
	InstallationDir string      `xml:"installation-directory,attr"`
	Version         string      `xml:"version,attr"`
	UpdateTime      time.Time   `xml:"date,attr"`
	Env             Environment `xml:"envvars"`
	CommandLineEnv  Environment `xml:"command-line"`
}

type DB struct {
	mu      sync.Mutex
	version Version
	path    string
	db      map[string]*Profile
}

// NewDB returns a new instance of a profile database.
func NewDB() *DB {
	return &DB{db: make(map[string]*Profile), version: V5}
}

// Path returns the directory or filename that this database was read from.
func (pdb *DB) Path() string {
	return pdb.path
}

// InstallProfile will create a new profile to the profiles database,
// it has no effect if the profile already exists. It returns the profile
// that was either newly created or already installed.
func (pdb *DB) InstallProfile(installer, name, root string) *Profile {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	qname := QualifiedProfileName(installer, name)
	if p := pdb.db[qname]; p == nil {
		pdb.db[qname] = &Profile{name: qname, root: root}
	}
	return pdb.db[qname]
}

// AddProfileTarget adds the specified target to the named profile.
// The UpdateTime of the newly installed target will be set to time.Now()
func (pdb *DB) AddProfileTarget(installer, name string, target Target) error {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	target.UpdateTime = time.Now()
	qname := QualifiedProfileName(installer, name)
	if pi, present := pdb.db[qname]; present {
		for _, t := range pi.Targets() {
			if target.Match(t) {
				return fmt.Errorf("%s is already used by profile %s %s", target, qname, pi.Targets())
			}
		}
		pi.targets = InsertTarget(pi.targets, &target)
		return nil
	}
	return fmt.Errorf("profile %v is not installed", qname)
}

// UpdateProfileTarget updates the specified target from the named profile.
// The UpdateTime of the updated target will be set to time.Now()
func (pdb *DB) UpdateProfileTarget(installer, name string, target Target) error {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	target.UpdateTime = time.Now()
	qname := QualifiedProfileName(installer, name)
	pi, present := pdb.db[qname]
	if !present {
		return fmt.Errorf("profile %v is not installed", qname)
	}
	for _, t := range pi.targets {
		if target.Match(t) {
			*t = target
			t.UpdateTime = time.Now()
			return nil
		}
	}
	return fmt.Errorf("profile %v does not have target: %v", qname, target)
}

// RemoveProfileTarget removes the specified target from the named profile.
// If this is the last target for the profile then the profile will be deleted
// from the database. It returns true if the profile was so deleted or did
// not originally exist.
func (pdb *DB) RemoveProfileTarget(installer, name string, target Target) bool {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	qname := QualifiedProfileName(installer, name)
	pi, present := pdb.db[qname]
	if !present {
		return true
	}
	pi.targets = RemoveTarget(pi.targets, &target)
	if len(pi.targets) == 0 {
		delete(pdb.db, qname)
		return true
	}
	return false
}

// Names returns the names, in lexicographic order, of all of the currently
// available profiles.
func (pdb *DB) Names() []string {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	return pdb.profilesUnlocked()
}

// Profiles returns all currently installed the profiles, in lexicographic order.
func (pdb *DB) Profiles() []*Profile {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	names := pdb.profilesUnlocked()
	r := make([]*Profile, len(names), len(names))
	for i, name := range names {
		r[i] = pdb.db[name]
	}
	return r
}

func (pdb *DB) profilesUnlocked() []string {
	names := make([]string, 0, len(pdb.db))
	for name := range pdb.db {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

// LookupProfile returns the profile for the supplied installer and profile
// name or nil if one is not found.
func (pdb *DB) LookupProfile(installer, name string) *Profile {
	qname := QualifiedProfileName(installer, name)
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	return pdb.db[qname]
}

// LookupProfileTarget returns the target information stored for the
// supplied installer, profile name and target.
func (pdb *DB) LookupProfileTarget(installer, name string, target Target) *Target {
	qname := QualifiedProfileName(installer, name)
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	mgr := pdb.db[qname]
	if mgr == nil {
		return nil
	}
	return FindTarget(mgr.targets, &target)
}

// EnvFromProfile obtains the environment variable settings from the specified
// profile and target. It returns nil if the target and/or profile could not
// be found.
func (pdb *DB) EnvFromProfile(installer, name string, target Target) []string {
	t := pdb.LookupProfileTarget(installer, name, target)
	if t == nil {
		return nil
	}
	return t.Env.Vars
}

func getDBFilenames(jirix *jiri.X, path string) (bool, []string, error) {
	s := jirix.NewSeq()
	isdir, err := s.IsDir(path)
	if err != nil {
		return false, nil, err
	}
	if !isdir {
		return false, []string{path}, nil
	}
	fis, err := s.ReadDir(path)
	if err != nil {
		return true, nil, err
	}
	paths := []string{}
	for _, fi := range fis {
		if strings.HasSuffix(fi.Name(), ".prev") {
			continue
		}
		paths = append(paths, filepath.Join(path, fi.Name()))
	}
	return true, paths, nil
}

// Read reads the specified database directory or file to obtain the current
// set of installed profiles into the receiver database. It is not
// an error if the database does not exist, instead, an empty database
// is returned.
func (pdb *DB) Read(jirix *jiri.X, path string) error {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	pdb.db = make(map[string]*Profile)
	isDir, filenames, err := getDBFilenames(jirix, path)
	if err != nil {
		return err
	}
	pdb.path = path
	s := jirix.NewSeq()
	for i, filename := range filenames {
		data, err := s.ReadFile(filename)
		if err != nil {
			// It's not an error if the database doesn't exist yet, it'll
			// just have no data in it and then be written out. This is the
			// case when starting with a new/empty repo. The original profiles
			// implementation behaved this way and I've tried to maintain it
			// without having to special case all of the call sites.
			if runutil.IsNotExist(err) {
				continue
			}
			return err
		}
		var schema profilesSchema
		if err := xml.Unmarshal(data, &schema); err != nil {
			return fmt.Errorf("Unmarshal(%v) failed: %v", string(data), err)
		}
		if isDir {
			if schema.Version < V5 {
				return fmt.Errorf("Profile database files must be at version %d (not %d) when more than one is found in a directory", V5, schema.Version)
			}
			if i >= 1 && pdb.version != schema.Version {
				return fmt.Errorf("Profile database files must have the same version (%d != %d) when more than one is found in a directory", pdb.version, schema.Version)
			}
		}
		pdb.version = schema.Version
		for _, p := range schema.Profiles {
			qname := QualifiedProfileName(schema.Installer, p.Name)
			pdb.db[qname] = &Profile{
				// Use the unqualified name in each profile since the
				// reader will read the installer from the xml installer
				// tag.
				name:      p.Name,
				installer: schema.Installer,
				root:      p.Root,
			}
			for _, target := range p.Targets {
				pdb.db[qname].targets = append(pdb.db[qname].targets, &Target{
					arch:            target.Arch,
					opsys:           target.OS,
					Env:             target.Env,
					commandLineEnv:  target.CommandLineEnv,
					version:         target.Version,
					UpdateTime:      target.UpdateTime,
					InstallationDir: target.InstallationDir,
					isSet:           true,
				})
			}
		}
	}
	return nil
}

// Write writes the current set of installed profiles to the specified
// database location. No data will be written and an error returned if the
// path is a directory and installer is an empty string.
func (pdb *DB) Write(jirix *jiri.X, installer, path string) error {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()

	if len(path) == 0 {
		return fmt.Errorf("please specify a profiles database path")
	}

	s := jirix.NewSeq()
	isdir, err := s.IsDir(path)
	if err != nil && !runutil.IsNotExist(err) {
		return err
	}
	filename := path
	if isdir {
		if installer == "" {
			return fmt.Errorf("no installer specified for directory path %v", path)
		}
		filename = filepath.Join(filename, installer)
	}

	var schema profilesSchema
	schema.Version = V5
	schema.Installer = installer
	for _, name := range pdb.profilesUnlocked() {
		profileInstaller, profileName := SplitProfileName(name)
		if profileInstaller != installer {
			continue
		}
		profile := pdb.db[name]
		current := &profileSchema{Name: profileName, Root: profile.root}
		schema.Profiles = append(schema.Profiles, current)

		for _, target := range profile.targets {
			sort.Strings(target.Env.Vars)
			if len(target.version) == 0 {
				return fmt.Errorf("missing version for profile %s target: %s", name, target)
			}
			current.Targets = append(current.Targets,
				&targetSchema{
					Arch:            target.arch,
					OS:              target.opsys,
					Env:             target.Env,
					CommandLineEnv:  target.commandLineEnv,
					Version:         target.version,
					InstallationDir: target.InstallationDir,
					UpdateTime:      target.UpdateTime,
				})
		}
	}

	data, err := xml.MarshalIndent(schema, "", "  ")
	if err != nil {
		return fmt.Errorf("MarshalIndent() failed: %v", err)
	}

	oldName := filename + ".prev"
	newName := filename + fmt.Sprintf(".%d", time.Now().UnixNano())

	if err := s.WriteFile(newName, data, defaultFileMode).
		AssertFileExists(filename).
		Rename(filename, oldName).Done(); err != nil && !runutil.IsNotExist(err) {
		return err
	}
	if err := s.Rename(newName, filename).Done(); err != nil {
		return err
	}
	return nil
}

// SchemaVersion returns the version of the xml schema used to implement
// the database.
func (pdb *DB) SchemaVersion() Version {
	pdb.mu.Lock()
	defer pdb.mu.Unlock()
	return pdb.version
}
