// 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/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.",
	}
}

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 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 := args
	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 profile.Targets() {
				fmt.Fprintf(jirix.Stdout(), "\t%s\n", target.DebugString())
			}
		}
		return nil
	}
	if listFlags.info == "" {
		if len(profileNames) > 0 {
			fmt.Fprintf(jirix.Stdout(), "%s\n", strings.Join(profileNames, ", "))
		}
		return nil
	}
	// Handle --info.
	for _, name := range profileNames {
		profile := rd.LookupProfile(name)
		out := &bytes.Buffer{}
		var targets profiles.Targets
		if listFlags.Target.IsSet() {
			targets = append(targets, rd.LookupProfileTarget(name, listFlags.Target))
		} else {
			targets = profile.Targets()
		}
		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")
			}
		}
		fmt.Fprint(jirix.Stdout(), out.String())
	}

	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 --profile-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(), " ")
}
