// 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 profilescmdline provides a command line driver (for v.io/x/lib/cmdline)
// for implementing jiri 'profile' subcommands. The intent is to support
// project specific instances of such profiles for managing software
// dependencies.
package profilescmdline

import (
	"flag"
	"fmt"
	"strings"

	"v.io/jiri/jiri"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilesmanager"
	"v.io/x/lib/cmdline"
)

// cmdInstall represents the "profile install" command.
var cmdInstall = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runInstall),
	Name:     "install",
	Short:    "Install the given profiles",
	Long:     "Install the given profiles.",
	ArgsName: "<profiles>",
	ArgsLong: "<profiles> is a list of profiles to install.",
}

// cmdUpdate represents the "profile update" command.
var cmdUpdate = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runUpdate),
	Name:     "update",
	Short:    "Install the latest default version of the given profiles",
	Long:     "Install the latest default version of the given profiles.",
	ArgsName: "<profiles>",
	ArgsLong: "<profiles> is a list of profiles to update, if omitted all profiles are updated.",
}

// cmdCleanup represents the "profile cleanup" command.
var cmdCleanup = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runCleanup),
	Name:     "cleanup",
	Short:    "Cleanup the locally installed profiles",
	Long:     "Cleanup the locally installed profiles. This is generally required when recovering from earlier bugs or when preparing for a subsequent change to the profiles implementation.",
	ArgsName: "<profiles>",
	ArgsLong: "<profiles> is a list of profiles to cleanup, if omitted all profiles are cleaned.",
}

// cmdUninstall represents the "profile uninstall" command.
var cmdUninstall = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runUninstall),
	Name:     "uninstall",
	Short:    "Uninstall the given profiles",
	Long:     "Uninstall the given profiles.",
	ArgsName: "<profiles>",
	ArgsLong: "<profiles> is a list of profiles to uninstall.",
}

func runUpdate(jirix *jiri.X, args []string) error {
	return updateImpl(jirix, &updateFlags, args)
}

func runCleanup(jirix *jiri.X, args []string) error {
	return cleanupImpl(jirix, &cleanupFlags, args)
}

func runInstall(jirix *jiri.X, args []string) error {
	return installImpl(jirix, &installFlags, args)
}

func runUninstall(jirix *jiri.X, args []string) error {
	return uninstallImpl(jirix, &uninstallFlags, args)
}

type commonFlagValues struct {
	// The value of --profiles-db
	dbFilename string
	// The value of --profile-root
	root string
}

type installFlagValues struct {
	commonFlagValues
	// The value of --target and --env
	target profiles.Target
	// The value of --force
	force bool
}

type uninstallFlagValues struct {
	commonFlagValues
	// The value of --target
	target profiles.Target
	// The value of --all-targets
	allTargets bool
	// The value of --v
	verbose bool
	// TODO(cnicolaou): add a flag to remove the profile only from the DB.
}

type updateFlagValues struct {
	commonFlagValues
	// The value of --v
	verbose bool
}

type cleanupFlagValues struct {
	commonFlagValues
	// The value of --gc
	gc bool
	// The value of --ensure-specific-versions-are-set
	ensureSpecificVersions bool
	// The value of --rewrite-profiles-manifest
	rewriteManifest bool
	// The value of --rm-all
	rmAll bool
	// The value of --v
	verbose bool
}

var (
	installFlags   installFlagValues
	uninstallFlags uninstallFlagValues
	cleanupFlags   cleanupFlagValues
	updateFlags    updateFlagValues
)

// RegisterManagementCommands registers the management subcommands:
// uninstall, install, update and cleanup.
//
func RegisterManagementCommands(parent *cmdline.Command, defaultDBFilename string) {
	initInstallCommand(&cmdInstall.Flags, defaultDBFilename)
	initUninstallCommand(&cmdUninstall.Flags, defaultDBFilename)
	initUpdateCommand(&cmdUpdate.Flags, defaultDBFilename)
	initCleanupCommand(&cmdCleanup.Flags, defaultDBFilename)
	parent.Children = append(parent.Children, cmdInstall, cmdUninstall, cmdUpdate, cmdCleanup)
}

func initCommon(flags *flag.FlagSet, c *commonFlagValues, defaultDBFilename string) {
	RegisterDBFilenameFlag(flags, &c.dbFilename, defaultDBFilename)
	flags.StringVar(&c.root, "profile-dir", "profiles", "the directory, relative to JIRI_ROOT, that profiles are installed in")
}

func initInstallCommand(flags *flag.FlagSet, defaultDBFilename string) {
	initCommon(flags, &installFlags.commonFlagValues, defaultDBFilename)
	profiles.RegisterTargetAndEnvFlags(flags, &installFlags.target)
	flags.BoolVar(&installFlags.force, "force", false, "force install the profile even if it is already installed")
}

func initUninstallCommand(flags *flag.FlagSet, defaultDBFilename string) {
	initCommon(flags, &uninstallFlags.commonFlagValues, defaultDBFilename)
	profiles.RegisterTargetFlag(flags, &uninstallFlags.target)
	flags.BoolVar(&uninstallFlags.allTargets, "all-targets", false, "apply to all targets for the specified profile(s)")
	flags.BoolVar(&uninstallFlags.verbose, "v", false, "print more detailed information")
}

func initUpdateCommand(flags *flag.FlagSet, defaultDBFilename string) {
	initCommon(flags, &updateFlags.commonFlagValues, defaultDBFilename)
	flags.BoolVar(&updateFlags.verbose, "v", false, "print more detailed information")
}

func initCleanupCommand(flags *flag.FlagSet, defaultDBFilename string) {
	initCommon(flags, &cleanupFlags.commonFlagValues, defaultDBFilename)
	flags.BoolVar(&cleanupFlags.gc, "gc", false, "uninstall profile targets that are older than the current default")
	flags.BoolVar(&cleanupFlags.ensureSpecificVersions, "ensure-specific-versions-are-set", false, "ensure that profile targets have a specific version set")
	flags.BoolVar(&cleanupFlags.rmAll, "rm-all", false, "remove profiles manifest and all profile generated output files.")
	flags.BoolVar(&cleanupFlags.rewriteManifest, "rewrite-profiles-manifest", false, "rewrite the profiles manifest file to use the latest schema version")
	flags.BoolVar(&cleanupFlags.verbose, "v", false, "print more detailed information")
}

// init a command that takes a list of profile managers as its arguments.
func initProfileManagersCommand(jirix *jiri.X, dbfile string, args []string) ([]string, *profiles.DB, error) {
	if len(args) == 0 {
		args = profilesmanager.Managers()
	} else {
		for _, n := range args {
			if mgr := profilesmanager.LookupManager(n); mgr == nil {
				avail := profilesmanager.Managers()
				return nil, nil, fmt.Errorf("profile %v is not one of the available ones: %s", n, strings.Join(avail, ", "))
			}
		}
	}
	db := profiles.NewDB()
	if err := db.Read(jirix, dbfile); err != nil {
		fmt.Fprintf(jirix.Stderr(), "Failed to read profiles database %q: %v", dbfile, err)
		return nil, nil, err
	}
	return args, db, nil
}

// init a command that takes a list of profiles (already installed) as
// its arguments.
func initProfilesCommand(jirix *jiri.X, dbfile string, args []string) ([]string, *profiles.DB, error) {
	db := profiles.NewDB()
	if err := db.Read(jirix, dbfile); err != nil {
		fmt.Fprintf(jirix.Stderr(), "Failed to read profiles database %q: %v", dbfile, err)
		return nil, nil, err
	}
	if len(args) == 0 {
		args = db.Names()
	} else {
		for _, n := range args {
			if p := db.LookupProfile(n); p == nil {
				avail := db.Names()
				return nil, nil, fmt.Errorf("profile %v is not one of the installed ones: %s", n, strings.Join(avail, ", "))
			}
		}
	}
	return args, db, nil
}

func updateImpl(jirix *jiri.X, cl *updateFlagValues, args []string) error {
	verbose := cl.verbose
	args, db, err := initProfileManagersCommand(jirix, cl.dbFilename, args)
	if err != nil {
		return err
	}
	for _, n := range args {
		mgr := profilesmanager.LookupManager(n)
		profile := db.LookupProfile(n)
		if profile == nil {
			continue
		}
		vi := mgr.VersionInfo()
		for _, target := range profile.Targets() {
			if vi.IsTargetOlderThanDefault(target.Version()) {
				if verbose {
					fmt.Fprintf(jirix.Stdout(), "Updating %s %s from %q to %s\n", n, target, target.Version(), vi)
				}
				target.SetVersion(vi.Default())
				err := mgr.Install(jirix, db, jiri.NewRelPath(cl.root), *target)
				logResult(jirix, "Update", mgr, *target, err)
				if err != nil {
					return err
				}
			} else {
				if verbose {
					fmt.Fprintf(jirix.Stdout(), "%s %s at %q is up to date(%s)\n", n, target, target.Version(), vi)
				}
			}
		}
	}
	return db.Write(jirix, cl.dbFilename)
}

func cleanupGC(jirix *jiri.X, db *profiles.DB, root jiri.RelPath, verbose bool, args []string) error {
	for _, name := range args {
		mgr := profilesmanager.LookupManager(name)
		if mgr == nil {
			fmt.Fprintf(jirix.Stderr(), "%s is not linked into this binary", name)
			continue
		}
		vi := mgr.VersionInfo()
		profile := db.LookupProfile(name)
		for _, target := range profile.Targets() {
			if vi.IsTargetOlderThanDefault(target.Version()) {
				err := mgr.Uninstall(jirix, db, root, *target)
				logResult(jirix, "gc", mgr, *target, err)
				if err != nil {
					return err
				}
			}
		}
	}
	return nil
}

func cleanupEnsureVersionsAreSet(jirix *jiri.X, db *profiles.DB, root jiri.RelPath, verbose bool, args []string) error {
	for _, name := range args {
		mgr := profilesmanager.LookupManager(name)
		if mgr == nil {
			fmt.Fprintf(jirix.Stderr(), "%s is not linked into this binary", name)
			continue
		}
		profile := db.LookupProfile(name)
		for _, target := range profile.Targets() {
			if len(target.Version()) == 0 {
				prior := *target
				version, err := mgr.VersionInfo().Select(target.Version())
				if err != nil {
					return err
				}
				target.SetVersion(version)
				db.RemoveProfileTarget(name, prior)
				if err := db.AddProfileTarget(name, *target); err != nil {
					return err
				}
				if verbose {
					fmt.Fprintf(jirix.Stdout(), "%s %s had no version, now set to: %s\n", name, prior, target)
				}
			}
		}
	}
	return nil
}

func cleanupRmAll(jirix *jiri.X, db *profiles.DB, root jiri.RelPath, verbose bool, args []string) error {
	s := jirix.NewSeq()
	if err := s.AssertFileExists(db.Filename()).Remove(db.Filename()).Done(); err != nil {
		return err
	}
	d := root.Abs(jirix)
	return s.AssertDirExists(d).
		Run("chmod", "-R", "u+w", d).
		RemoveAll(d).
		Done()
}

func cleanupImpl(jirix *jiri.X, cl *cleanupFlagValues, args []string) error {
	args, db, err := initProfilesCommand(jirix, cl.dbFilename, args)
	if err != nil {
		return err
	}
	verbose := cl.verbose
	root := jiri.NewRelPath(cl.root)
	dirty := false
	if cl.ensureSpecificVersions {
		if verbose {
			fmt.Fprintf(jirix.Stdout(), "Ensuring that all targets have a specific version set for %s\n", args)
		}
		if err := cleanupEnsureVersionsAreSet(jirix, db, root, verbose, args); err != nil {
			return fmt.Errorf("ensure-specific-versions-are-set: %v", err)
		}
		dirty = true
	}
	if cl.gc {
		if verbose {
			fmt.Fprintf(jirix.Stdout(), "Removing targets older than the default version for %s\n", args)
		}
		if err := cleanupGC(jirix, db, root, verbose, args); err != nil {
			return fmt.Errorf("gc: %v", err)
		}
		dirty = true
	}
	if cl.rmAll {
		if verbose {
			fmt.Fprintf(jirix.Stdout(), "Removing profile manifest and all profile output files\n")
		}
		if err := cleanupRmAll(jirix, db, root, verbose, args); err != nil {
			return err
		}
		// Don't write out the profiles manifest file again.
		return nil
	}
	if cl.rewriteManifest {
		dirty = true
	}
	if !dirty {
		return fmt.Errorf("at least one option must be specified")
	}
	return db.Write(jirix, cl.dbFilename)
}

func logResult(jirix *jiri.X, action string, mgr profiles.Manager, target profiles.Target, err error) {
	fmt.Fprintf(jirix.Stdout(), "%s: %s %s: ", action, mgr.Name(), target)
	if err == nil {
		fmt.Fprintf(jirix.Stdout(), "success\n")
	} else {
		fmt.Fprintf(jirix.Stdout(), "%v\n", err)
	}
}

func targetAtDefaultVersion(mgr profiles.Manager, target profiles.Target) (profiles.Target, error) {
	def := target
	version, err := mgr.VersionInfo().Select(target.Version())
	if err != nil {
		return profiles.Target{}, err
	}
	def.SetVersion(version)
	return def, nil
}

func installImpl(jirix *jiri.X, cl *installFlagValues, args []string) error {
	args, db, err := initProfileManagersCommand(jirix, cl.dbFilename, args)
	if err != nil {
		return err
	}
	root := jiri.NewRelPath(cl.root)
	cl.target.UseCommandLineEnv()
	names := []string{}
	if cl.force {
		names = args
	} else {
		for _, name := range args {
			if p := db.LookupProfileTarget(name, cl.target); p != nil {
				fmt.Fprintf(jirix.Stdout(), "%v %v is already installed as %v\n", name, cl.target, p)
				continue
			}
			names = append(names, name)
		}
	}
	for _, name := range names {
		mgr := profilesmanager.LookupManager(name)
		def, err := targetAtDefaultVersion(mgr, cl.target)
		if err != nil {
			return err
		}
		err = mgr.Install(jirix, db, root, def)
		logResult(jirix, "Install:", mgr, def, err)
		if err != nil {
			return err
		}
	}
	return db.Write(jirix, cl.dbFilename)
}

func uninstallImpl(jirix *jiri.X, cl *uninstallFlagValues, args []string) error {
	args, db, err := initProfileManagersCommand(jirix, cl.dbFilename, args)
	if err != nil {
		return err
	}
	root := jiri.NewRelPath(cl.root)
	if cl.allTargets && cl.target.IsSet() {
		fmt.Fprintf(jirix.Stdout(), "ignore target (%v) when used in conjunction with --all-targets\n", cl.target)
	}
	for _, name := range args {
		profile := db.LookupProfile(name)
		if profile == nil {
			continue
		}
		mgr := profilesmanager.LookupManager(name)
		var targets []*profiles.Target
		if cl.allTargets {
			targets = profile.Targets()
		} else {
			def, err := targetAtDefaultVersion(mgr, cl.target)
			if err != nil {
				return err
			}
			targets = []*profiles.Target{&def}
		}
		for _, target := range targets {
			if err := mgr.Uninstall(jirix, db, root, *target); err != nil {
				logResult(jirix, "Uninstall", mgr, *target, err)
				return err
			}
			logResult(jirix, "Uninstall", mgr, *target, nil)

		}
	}
	return db.Write(jirix, cl.dbFilename)
}
