// 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"
	"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): 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)
			if profile == nil {
				continue
			}
			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 profile == nil {
				continue
			}
			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)
		if profile == nil {
			continue
		}
		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 && IsFlagSet(cmdList.ParsedFlags, "target") {
		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.NewUTF8WrapWriter(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(), " ")
}
