// 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 (
	"bytes"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"text/template"

	"v.io/jiri"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilesreader"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/textutil"
)

// IsFlagSet returns true if the specified flag has been set on
// the command line.
func IsFlagSet(fs *flag.FlagSet, name string) bool {
	found := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			found = true
		}
	})
	return found
}

// NOTE: we use functions to initialize the commands so that we
// can reinitialize them in tests. cmd_test.go contains a 'Reset' function
// that is only available to tests for doing so.
// NOTE: we can't set cmdList.Runner in the initialization loop since runList
// needs to access cmdList.Flags.
var (
	// cmdList represents the "profile list" command.
	cmdList *cmdline.Command
	// cmdEnv represents the "profile env" command.
	cmdEnv *cmdline.Command = newCmdEnv()
)

func init() {
	cmdList = newCmdList()
	cmdList.Runner = jiri.RunnerFunc(runList)
}

func newCmdList() *cmdline.Command {
	return &cmdline.Command{
		Name:     "list",
		Short:    "List available or installed profiles",
		Long:     "List available or installed profiles.",
		ArgsName: "[<profiles>]",
		ArgsLong: `<profiles> is a list of profiles to list, defaulting to all
profiles if none are specifically requested. List can also be used
to test for the presence of a specific target for the requested profiles.
If the target is not installed, it will exit with an error.`,
	}
}

func newCmdEnv() *cmdline.Command {
	// cmdEnv represents the "profile env" command.
	return &cmdline.Command{
		Runner: jiri.RunnerFunc(runEnv),
		Name:   "env",
		Short:  "Display profile environment variables",
		Long: `
List profile specific and target specific environment variables. If the
requested environment variable name ends in = then only the value will
be printed, otherwise both name and value are printed, i.e. GOPATH="foo" vs
just "foo".

If no environment variable names are requested then all will be printed
in <name>=<val> format.
`,
		ArgsName: "[<environment variable names>]",
		ArgsLong: "[<environment variable names>] is an optional list of environment variables to display",
	}
}

// ReaderFlagValues contains the values of the command line flags accepted
// required to configure and use the profiles/Reader package.
type ReaderFlagValues struct {
	// The value of --skip-profiles
	ProfilesMode profilesreader.ProfilesMode
	// The value of --profiles-db
	DBFilename string
	// The value of --profiles
	Profiles string
	// The value of --target and --env
	Target profiles.Target
	// The value of --merge-policies
	MergePolicies profilesreader.MergePolicies
	// The value of -v
	Verbose bool
}

// listFlagValues contains the flag values expected by the list subcommand
type listFlagValues struct {
	*ReaderFlagValues
	// The value of --info
	info string
}

// envFlagValues contains the flag values expected by the env subcommand
type envFlagValues struct {
	*ReaderFlagValues
}

// All flag values are stored in listFlags and envFlags.
var (
	listFlags listFlagValues
	envFlags  envFlagValues
)

// RegisterDBPathFlag registers the --profiles-db flag with the supplied FlagSet.
func RegisterDBPathFlag(flags *flag.FlagSet, manifest *string, defaultDBPath string) {
	root := jiri.FindRoot()
	flags.StringVar(manifest, "profiles-db", filepath.Join(root, defaultDBPath), "the path, relative to JIRI_ROOT, that contains the profiles database.")
	flags.Lookup("profiles-db").DefValue = filepath.Join("$JIRI_ROOT", defaultDBPath)
}

// RegisterProfilesFlag registers the --profiles flag
func RegisterProfilesFlag(flags *flag.FlagSet, profiles *string) {
	// TODO(cnicolaou): delete this when the new profiles are in use.
	root := jiri.FindRoot()
	fi, err := os.Stat(filepath.Join(root, jiri.ProfilesDBDir))
	defaultProfiles := "base,jiri"
	if err == nil && fi.IsDir() {
		// TODO(cnicolaou): we need a better way of setting the default profiles,
		// ideally via the profiles db, or some other config. Provide a command
		// line tool for setting the default profiles.
		defaultProfiles = "v23:base,jiri"
	}
	flags.StringVar(profiles, "profiles", defaultProfiles, "a comma separated list of profiles to use")
}

// RegisterMergePoliciesFlag registers the --merge-policies flag
func RegisterMergePoliciesFlag(flags *flag.FlagSet, policies *profilesreader.MergePolicies) {
	flags.Var(policies, "merge-policies", "specify policies for merging environment variables")
}

// RegisterReaderFlags registers the 'reader' flags (see below)
// with the parent command. The values of the flags can be accessed via
// the supplied ReaderFlagValues struct.
// The reader flags are:
//  --skip-profiles
//  --profiles-db
//  --profiles
//  --merge-policies
//  --target and --env
func RegisterReaderFlags(flags *flag.FlagSet, fv *ReaderFlagValues, defaultDBPath string) {
	flags.Var(&fv.ProfilesMode, "skip-profiles", "if set, no profiles will be used")
	RegisterDBPathFlag(flags, &fv.DBFilename, defaultDBPath)
	RegisterProfilesFlag(flags, &fv.Profiles)
	fv.MergePolicies = profilesreader.JiriMergePolicies()
	RegisterMergePoliciesFlag(flags, &fv.MergePolicies)
	profiles.RegisterTargetAndEnvFlags(flags, &fv.Target)
}

// RegisterReaderCommandsUsingParent registers the 'reader' flags
// (see RegisterReaderFlags) with the parent command and creates the
// list and env subcommands. The values of the flags can be accessed via
// the supplied ReaderFlagValues struct.
// RegisterReaderCommandsUsingParent results in a command line of the form:
// <parent> <reader-flags> [list|env] <list/env specific commands>
func RegisterReaderCommandsUsingParent(parent *cmdline.Command, fv *ReaderFlagValues, defaultDBPath string) {
	envFlags.ReaderFlagValues = fv
	listFlags.ReaderFlagValues = fv
	RegisterReaderFlags(&parent.Flags, fv, defaultDBPath)
	RegisterReaderCommands(parent, defaultDBPath)
}

// RegisterReaderCommands registers the list and env subcommands. The
// subcommands will host the 'reader' flags (see RegisterReaderFlags)
// resulting in a command line of the form:
// <parent> [list|env] <reader-flags> <list/env specific specific commands>
func RegisterReaderCommands(parent *cmdline.Command, defaultDBPath string) {
	registerListCommand(parent, defaultDBPath)
	registerEnvCommand(parent, defaultDBPath)
}

func newReaderFlags() *ReaderFlagValues {
	return &ReaderFlagValues{MergePolicies: profilesreader.JiriMergePolicies()}
}

// registerListCommand the profiles list subcommand and returns it
// and a struct containing  the values of the command line flags.
func registerListCommand(parent *cmdline.Command, defaultDBPath string) {
	parent.Children = append(parent.Children, cmdList)
	if listFlags.ReaderFlagValues == nil {
		listFlags.ReaderFlagValues = newReaderFlags()
		RegisterReaderFlags(&cmdList.Flags, listFlags.ReaderFlagValues, defaultDBPath)
	}
	cmdList.Flags.BoolVar(&listFlags.Verbose, "v", false, "print more detailed information")
	cmdList.Flags.StringVar(&listFlags.info, "info", "", infoUsage())
}

// registerEnvCommand the profiles env subcommand and returns it and a
// struct containing the values of the command line flags.
func registerEnvCommand(parent *cmdline.Command, defaultDBPath string) {
	parent.Children = append(parent.Children, cmdEnv)
	if envFlags.ReaderFlagValues == nil {
		envFlags.ReaderFlagValues = newReaderFlags()
		RegisterReaderFlags(&cmdEnv.Flags, envFlags.ReaderFlagValues, defaultDBPath)
	}
	cmdEnv.Flags.BoolVar(&envFlags.Verbose, "v", false, "print more detailed information")
}

func matchingTargets(rd *profilesreader.Reader, profile *profiles.Profile) profiles.Targets {
	var targets profiles.Targets
	if IsFlagSet(cmdList.ParsedFlags, "target") {
		if t := rd.LookupProfileTarget(profile.Name(), listFlags.Target); t != nil {
			targets = profiles.Targets{t}
		}
	} else {
		targets = profile.Targets()
	}
	targets.Sort()
	return targets
}

func runList(jirix *jiri.X, args []string) error {
	if listFlags.Verbose {
		fmt.Fprintf(jirix.Stdout(), "Profiles Database Path: %s\n", listFlags.DBFilename)
	}
	rd, err := profilesreader.NewReader(jirix, listFlags.ProfilesMode, listFlags.DBFilename)
	if err != nil {
		return err
	}
	profileNames := []string{}
	for _, a := range args {
		if a != "" {
			profileNames = append(profileNames, a)
		}
	}
	if len(args) == 0 {
		if IsFlagSet(cmdList.ParsedFlags, "profiles") {
			profileNames = strings.Split(listFlags.Profiles, ",")
		} else {
			profileNames = rd.ProfileNames()
		}
	}

	if listFlags.Verbose {
		fmt.Fprintf(jirix.Stdout(), "Installed Profiles: ")
		fmt.Fprintf(jirix.Stdout(), "%s\n", strings.Join(rd.ProfileNames(), ", "))
		for _, name := range profileNames {
			profile := rd.LookupProfile(name)
			fmt.Fprintf(jirix.Stdout(), "Profile: %s @ %s\n", profile.Name(), profile.Root())
			for _, target := range matchingTargets(rd, profile) {
				fmt.Fprintf(jirix.Stdout(), "\t%s\n", target.DebugString())
			}
		}
		return nil
	}
	if listFlags.info == "" {
		matchingNames := []string{}
		for _, name := range profileNames {
			profile := rd.LookupProfile(name)
			if len(matchingTargets(rd, profile)) > 0 {
				matchingNames = append(matchingNames, name)
			}
		}
		if len(matchingNames) > 0 {
			fmt.Fprintln(jirix.Stdout(), strings.Join(matchingNames, ", "))
		} else {
			if IsFlagSet(cmdList.ParsedFlags, "target") {
				return fmt.Errorf("no matching targets for %s", listFlags.Target)
			}
		}
		return nil
	}
	// Handle --info
	found := false
	for _, name := range profileNames {
		profile := rd.LookupProfile(name)
		targets := matchingTargets(rd, profile)
		out := &bytes.Buffer{}
		printHeader := len(profileNames) > 1 || len(targets) > 1 || len(listFlags.info) == 0
		for _, target := range targets {
			if printHeader {
				out.WriteString(fmtHeader(name, target))
				out.WriteString(" ")
			}
			r, err := fmtInfo(jirix, listFlags.info, rd, profile, target)
			if err != nil {
				return err
			}
			out.WriteString(r)
			if printHeader {
				out.WriteString("\n")
			}
			found = true
		}
		fmt.Fprint(jirix.Stdout(), out.String())
	}
	if !found {
		return fmt.Errorf("no matching targets for %s", listFlags.Target)
	}
	return nil
}

func fmtHeader(name string, target *profiles.Target) string {
	if target == nil {
		return name
	}
	return name + " " + target.String()
}

type listInfo struct {
	SchemaVersion profiles.Version
	DBPath        string
	Target        struct {
		InstallationDir string
		CommandLineEnv  []string
		Env             []string
		Command         string
	}
	Profile struct {
		Root      string
		Name      string
		Installer string
		DBPath    string
	}
}

func infoUsage() string {
	return `The following fields for use with -info are available:
	SchemaVersion - the version of the profiles implementation.
	DBPath - the path for the profiles database.
	Target.InstallationDir - the installation directory of the requested profile.
	Target.CommandLineEnv - the environment variables specified via the command line when installing this profile target.
	Target.Env - the environment variables computed by the profile installation process for this target.
	Target.Command - a command that can be used to create this profile.
	Note: if no --target is specified then the requested field will be displayed for all targets.

	Profile.Root - the root directory of the requested profile.
	Profile.Name - the qualified name of the profile.
	Profile.Installer - the name of the profile installer.
	Profile.DBPath - the path to the database file for this profile.
	Note: if no profiles are specified then the requested field will be displayed for all profiles.`
}

func fmtOutput(jirix *jiri.X, o string) string {
	_, width, err := textutil.TerminalSize()
	if err != nil {
		width = 80
	}
	if len(o) < width {
		return o
	}
	out := &bytes.Buffer{}
	w := textutil.NewUTF8LineWriter(out, width)
	fmt.Fprint(w, o)
	w.Flush()
	return out.String()
}

func fmtInfo(jirix *jiri.X, infoFmt string, rd *profilesreader.Reader, profile *profiles.Profile, target *profiles.Target) (string, error) {
	// Populate an instance listInfo
	info := &listInfo{}
	name := profile.Name()
	installer, _ := profiles.SplitProfileName(name)
	info.SchemaVersion = rd.SchemaVersion()
	info.DBPath = rd.Path()
	if target != nil {
		info.Target.InstallationDir = jiri.NewRelPath(target.InstallationDir).Abs(jirix)
		info.Target.CommandLineEnv = target.CommandLineEnv().Vars
		info.Target.Env = target.Env.Vars
		clenv := ""
		if len(info.Target.CommandLineEnv) > 0 {
			clenv = fmt.Sprintf(" --env=\"%s\" ", strings.Join(info.Target.CommandLineEnv, ","))
		}
		if installer != "" {
			info.Target.Command = fmt.Sprintf("jiri profile install --target=%s %s%s", target, clenv, name)
		} else {
			// TODO(cnicolaou): remove this when the transition is complete.
			info.Target.Command = fmt.Sprintf("jiri v23-profile install --target=%s %s%s", target, clenv, name)
		}
	}
	if profile != nil {
		rp := jiri.NewRelPath(profile.Root())
		info.Profile.Root = rp.Abs(jirix)
		info.Profile.Name = name
		info.Profile.Installer = installer
		info.Profile.DBPath = info.DBPath
		if installer != "" {
			info.Profile.DBPath = filepath.Join(info.DBPath, installer)
		}
	}

	// Use a template to print out any field in our instance of listInfo.
	tmpl, err := template.New("list").Parse("{{ ." + infoFmt + "}}")
	if err != nil {
		return "", err
	}
	out := &bytes.Buffer{}
	if err = tmpl.Execute(out, info); err != nil {
		return "", fmt.Errorf("please specify a supported field:\n%s", infoUsage())
	}
	return out.String(), nil
}

func runEnv(jirix *jiri.X, args []string) error {
	if len(envFlags.Profiles) == 0 {
		return fmt.Errorf("no profiles were specified using --profiles")
	}
	rd, err := profilesreader.NewReader(jirix, envFlags.ProfilesMode, envFlags.DBFilename)
	if err != nil {
		return err
	}
	profileNames := strings.Split(envFlags.Profiles, ",")
	if err := rd.ValidateRequestedProfilesAndTarget(profileNames, envFlags.Target); err != nil {
		return err
	}
	rd.MergeEnvFromProfiles(envFlags.MergePolicies, envFlags.Target, profileNames...)
	out := fmtVars(rd.ToMap(), args)
	if len(out) > 0 {
		fmt.Fprintln(jirix.Stdout(), out)
	}
	return nil
}

func expr(k, v string, trimmed bool) string {
	if trimmed {
		return v
	}
	return fmt.Sprintf("%s=%q ", k, v)
}

func fmtVars(vars map[string]string, args []string) string {
	buf := bytes.Buffer{}
	if len(args) == 0 {
		for k, v := range vars {
			buf.WriteString(fmt.Sprintf("%s=%q ", k, v))
		}
	} else {
		for _, arg := range args {
			name := strings.TrimSuffix(arg, "=")
			trimmed := name != arg
			for k, v := range vars {
				if k == name {
					buf.WriteString(expr(k, v, trimmed))
				}
			}
		}
	}
	return strings.TrimSuffix(buf.String(), " ")
}
