// 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 commandline 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 commandline

import (
	"bytes"
	"flag"
	"fmt"
	"path/filepath"
	"strings"
	"text/template"

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

const DefaultProfiles = "base,jiri"

// IsFlagSet returns true if the specified flag has been set on
// the command line.
// TODO(cnicolaou): use this to simplify the implementation of profiles.Target
func IsFlagSet(fs *flag.FlagSet, name string) bool {
	found := false
	fs.Visit(func(f *flag.Flag) {
		if f.Name == name {
			found = true
		}
	})
	return true
}

// 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 reader.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 reader.MergePolicies
	// The value of -v
	Verbose bool
}

// listFlagValues contains the flag values expected by the list subcommand
type listFlagValues struct {
	*ReaderFlagValues
	// The value of --show-profiles-db
	showProfilesDB bool
	// The value of --available
	available bool
	// 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
)

// RegisterDBFilenameFlag registers the --profiles-db flag with the supplied FlagSet.
func RegisterDBFilenameFlag(flags *flag.FlagSet, manifest *string, defaultManifest string) {
	root := jiri.FindRoot()
	flags.StringVar(manifest, "profiles-db", filepath.Join(root, defaultManifest), "specify the profiles XML manifest filename.")
	flags.Lookup("profiles-db").DefValue = filepath.Join("$JIRI_ROOT", defaultManifest)
}

// RegisterProfilesFlag registers the --profiles flag
func RegisterProfilesFlag(flags *flag.FlagSet, profiles *string) {
	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 *reader.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, defaultDBFilename string) {
	flags.Var(&fv.ProfilesMode, "skip-profiles", "if set, no profiles will be used")
	RegisterDBFilenameFlag(flags, &fv.DBFilename, defaultDBFilename)
	RegisterProfilesFlag(flags, &fv.Profiles)
	fv.MergePolicies = reader.JiriMergePolicies()
	RegisterMergePoliciesFlag(flags, &fv.MergePolicies)
	profiles.RegisterTargetAndEnvFlags(flags, &fv.Target)
}

func initializeReaderFlags(flags *flag.FlagSet, fv *ReaderFlagValues, defaultDBFilename string) {
	envFlags.ReaderFlagValues = fv
	listFlags.ReaderFlagValues = fv
	RegisterReaderFlags(flags, fv, defaultDBFilename)
}

// 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, defaultDBFilename string) {
	initializeReaderFlags(&parent.Flags, fv, defaultDBFilename)
	RegisterReaderCommands(parent, defaultDBFilename)
}

// 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, defaultDBFilename string) {
	registerListCommand(parent, defaultDBFilename)
	registerEnvCommand(parent, defaultDBFilename)
}

func newReaderFlags() *ReaderFlagValues {
	return &ReaderFlagValues{MergePolicies: reader.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, defaultDBFilename string) {
	parent.Children = append(parent.Children, cmdList)
	if listFlags.ReaderFlagValues == nil {
		listFlags.ReaderFlagValues = newReaderFlags()
		RegisterReaderFlags(&cmdList.Flags, listFlags.ReaderFlagValues, defaultDBFilename)
	}
	cmdList.Flags.BoolVar(&listFlags.Verbose, "v", false, "print more detailed information")
	cmdList.Flags.BoolVar(&listFlags.showProfilesDB, "show-profiles-db", false, "print out the profiles database file")
	cmdList.Flags.BoolVar(&listFlags.available, "available", false, "print the list of available profiles")
	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, defaultDBFilename string) {
	parent.Children = append(parent.Children, cmdEnv)
	if envFlags.ReaderFlagValues == nil {
		envFlags.ReaderFlagValues = newReaderFlags()
		RegisterReaderFlags(&cmdEnv.Flags, envFlags.ReaderFlagValues, defaultDBFilename)
	}
	cmdEnv.Flags.BoolVar(&envFlags.Verbose, "v", false, "print more detailed information")
}

func runList(jirix *jiri.X, args []string) error {
	if listFlags.showProfilesDB {
		data, err := jirix.NewSeq().ReadFile(listFlags.DBFilename)
		if err != nil {
			return err
		}
		fmt.Fprintln(jirix.Stdout(), string(data))
		return nil
	}
	if listFlags.Verbose {
		fmt.Fprintf(jirix.Stdout(), "Profiles Database Filename: %s\n", listFlags.DBFilename)
	}
	if listFlags.available {
		if listFlags.Verbose {
			fmt.Fprintf(jirix.Stdout(), "Available Profiles:\n")
			for _, name := range manager.Managers() {
				mgr := manager.LookupManager(name)
				vi := mgr.VersionInfo()
				fmt.Fprintf(jirix.Stdout(), "%s: versions: %s\n", name, vi)
			}
		} else {
			fmt.Fprintf(jirix.Stdout(), "%s\n", strings.Join(manager.Managers(), ", "))
		}
	}
	rd, err := reader.NewReader(jirix, listFlags.ProfilesMode, listFlags.DBFilename)
	if err != nil {
		return err
	}
	profileNames := args
	if len(args) == 0 {
		if IsFlagSet(&cmdList.Flags, "profiles") {
			profileNames = strings.Split(listFlags.Profiles, ",")
		} else {
			profileNames = rd.ProfileNames()
		}
	}
	availableNames := []string{}
	for _, name := range profileNames {
		if rd.LookupProfile(name) != nil {
			availableNames = append(availableNames, name)
		}
	}
	if listFlags.Verbose {
		fmt.Fprintf(jirix.Stdout(), "Installed Profiles: ")
		fmt.Fprintf(jirix.Stdout(), "%s\n", strings.Join(rd.ProfileNames(), ", "))
		for _, name := range availableNames {
			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())
			}
		}
	} else {
		for _, name := range availableNames {
			profile := rd.LookupProfile(name)
			mgr := manager.LookupManager(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(availableNames) > 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, mgr, 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
	Target        struct {
		InstallationDir string
		CommandLineEnv  []string
		Env             []string
		Command         string
	}
	Profile struct {
		Description    string
		Root           string
		DefaultVersion string
		LatestVersion  string
		Versions       []string
	}
}

func infoUsage() string {
	return `The following fields for use with --profile-info are available:
	SchemaVersion - the version of the profiles implementation.
	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.Description - description of the requested profile.
	Profile.Root - the root directory of the requested profile.
	Profile.Versions - the set of supported versions for this profile.
	Profile.DefaultVersion - the default version of the requested profile.
	Profile.LatestVersion - the latest version available for the requested 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 *reader.Reader, mgr profiles.Manager, profile *profiles.Profile, target *profiles.Target) (string, error) {
	if len(infoFmt) > 0 {
		// Populate an instance listInfo
		info := &listInfo{}
		name := ""
		if mgr != nil {
			// Format the description on its own, without any preceeding
			// text so that the line breaks work correctly.
			info.Profile.Description = "\n" + fmtOutput(jirix, mgr.Info()) + "\n"
			vi := mgr.VersionInfo()
			if supported := vi.Supported(); len(supported) > 0 {
				info.Profile.Versions = supported
				info.Profile.LatestVersion = supported[0]
			}
			info.Profile.DefaultVersion = vi.Default()
			name = mgr.Name()
		}
		info.SchemaVersion = rd.SchemaVersion()
		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, ","))
			}
			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)
		}

		// 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
	}
	return "", 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 := reader.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(), " ")
}
