// Copyright 2017 The Fuchsia 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 main

import (
	"encoding/json"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"strings"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/cmdline"
	"go.fuchsia.dev/jiri/gitutil"
	"go.fuchsia.dev/jiri/project"
)

type arrayFlag []string

func (i *arrayFlag) String() string {
	return strings.Join(*i, ", ")
}

func (i *arrayFlag) Set(value string) error {
	*i = append(*i, value)
	return nil
}

var editFlags struct {
	projects   arrayFlag
	imports    arrayFlag
	packages   arrayFlag
	jsonOutput string
	editMode   string
}

const (
	manifest = "manifest"
	lockfile = "lockfile"
	both     = "both"
)

type projectChanges struct {
	Name   string `json:"name"`
	Remote string `json:"remote"`
	Path   string `json:"path"`
	OldRev string `json:"old_revision"`
	NewRev string `json:"new_revision"`
}

type importChanges struct {
	Name   string `json:"name"`
	Remote string `json:"remote"`
	OldRev string `json:"old_revision"`
	NewRev string `json:"new_revision"`
}

type packageChanges struct {
	Name   string `json:"name"`
	OldVer string `json:"old_version"`
	NewVer string `json:"new_version"`
}

type editChanges struct {
	Projects []projectChanges `json:"projects"`
	Imports  []importChanges  `json:"imports"`
	Packages []packageChanges `json:"packages"`
}

func (ec *editChanges) toFile(filename string) error {
	if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
		return err
	}
	out, err := json.MarshalIndent(ec, "", "  ")
	if err != nil {
		return fmt.Errorf("failed to serialize JSON output: %s\n", err)
	}

	err = os.WriteFile(filename, out, 0600)
	if err != nil {
		return fmt.Errorf("failed write JSON output to %s: %s\n", filename, err)
	}

	return nil
}

// TODO(IN-361): Make this a subcommand of 'manifest'
var cmdEdit = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runEdit),
	Name:     "edit",
	Short:    "Edit manifest file",
	Long:     `Edit manifest file by rolling the revision of provided projects, imports or packages`,
	ArgsName: "<manifest>",
	ArgsLong: "<manifest> is path of the manifest",
}

func init() {
	flags := &cmdEdit.Flags
	flags.Var(&editFlags.projects, "project", "List of projects to update. It is of form <project-name>=<revision> where revision is optional. It can be specified multiple times.")
	flags.Var(&editFlags.imports, "import", "List of imports to update. It is of form <import-name>=<revision> where revision is optional. It can be specified multiple times.")
	flags.Var(&editFlags.packages, "package", "List of packages to update. It is of form <package-name>=<version>. It can be specified multiple times.")
	flags.StringVar(&editFlags.jsonOutput, "json-output", "", "File to print changes to, in json format.")
	flags.StringVar(&editFlags.editMode, "edit-mode", "both", "Edit mode. It can be 'manifest' for updating project revisions in manifest only, 'lockfile' for updating project revisions in lockfile only or 'both' for updating project revisions in both files.")
}

func runEdit(jirix *jiri.X, args []string) error {
	if len(args) != 1 {
		return jirix.UsageErrorf("Wrong number of args")
	}

	editFlags.editMode = strings.ToLower(editFlags.editMode)
	if editFlags.editMode != manifest && editFlags.editMode != lockfile && editFlags.editMode != both {
		return fmt.Errorf("unsupported edit-mode: %q", editFlags.editMode)
	}

	manifestPath, err := filepath.Abs(args[0])
	if err != nil {
		return err
	}
	if len(editFlags.projects) == 0 && len(editFlags.imports) == 0 && len(editFlags.packages) == 0 {
		return jirix.UsageErrorf("Please provide -project, -import and/or -package flag")
	}
	projects := make(map[string]string)
	imports := make(map[string]string)
	packages := make(map[string]string)
	for _, p := range editFlags.projects {
		s := strings.SplitN(p, "=", 2)
		if len(s) == 1 {
			projects[s[0]] = ""
		} else {
			projects[s[0]] = s[1]
		}
	}
	for _, i := range editFlags.imports {
		s := strings.SplitN(i, "=", 2)
		if len(s) == 1 {
			imports[s[0]] = ""
		} else {
			imports[s[0]] = s[1]
		}
	}
	for _, p := range editFlags.packages {
		// The package name may contain "=" characters; so we split the string from the rightmost "=".
		separatorPos := strings.LastIndex(p, "=");
		if separatorPos == -1 || separatorPos == 0 || separatorPos == len(p) - 1 {
			return jirix.UsageErrorf("Please provide the -package flag in the form <package-name>=<version>")
		} else {
			packageName := p[:separatorPos]
			version := p[separatorPos + 1:]
			packages[packageName] = version
		}
	}

	return updateManifest(jirix, manifestPath, projects, imports, packages)
}

func writeManifest(jirix *jiri.X, manifestPath, manifestContent string, projects map[string]string) error {
	// Create a temp dir to save backedup lockfiles
	tempDir, err := os.MkdirTemp("", "jiri_lockfile")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempDir)

	// map "backup" stores the mapping between updated lockfile with backups
	backup := make(map[string]string)
	rewind := func() {
		for k, v := range backup {
			if err := os.Rename(v, k); err != nil {
				jirix.Logger.Errorf("failed to revert changes to lockfile %q", k)
			} else {
				jirix.Logger.Debugf("reverted lockfile %q", k)
			}
		}
	}

	isLockfileDir := func(jirix *jiri.X, s string) bool {
		switch s {
		case "", ".", jirix.Root, string(filepath.Separator):
			return false
		}
		return true
	}

	if len(projects) != 0 && (editFlags.editMode == lockfile || editFlags.editMode == both) {
		// Search lockfiles and update
		dir := manifestPath
		for ; isLockfileDir(jirix, dir); dir = path.Dir(dir) {
			lockfile := path.Join(path.Dir(dir), jirix.LockfileName)

			if _, err := os.Stat(lockfile); err != nil {
				jirix.Logger.Debugf("lockfile could not be accessed at %q due to error %v", lockfile, err)
				continue
			}
			if err := updateLocks(jirix, tempDir, lockfile, backup, projects); err != nil {
				rewind()
				return err
			}
		}
	}

	if err := os.WriteFile(manifestPath, []byte(manifestContent), os.ModePerm); err != nil {
		rewind()
		return err
	}
	return nil
}

func updateLocks(jirix *jiri.X, tempDir, lockfile string, backup, projects map[string]string) error {
	jirix.Logger.Debugf("try updating lockfile %q", lockfile)
	bin, err := os.ReadFile(lockfile)
	if err != nil {
		return err
	}

	projectLocks, packageLocks, err := project.UnmarshalLockEntries(bin)
	if err != nil {
		return err
	}

	found := false
	for k, v := range projectLocks {
		if newRev, ok := projects[k.String()]; ok {
			v.Revision = newRev
			projectLocks[k] = v
			found = true
		}
	}

	if found {
		// backup original lockfile
		info, err := os.Stat(lockfile)
		if err != nil {
			return err
		}
		backupName := path.Join(tempDir, path.Base(lockfile))
		if err := os.WriteFile(backupName, bin, info.Mode()); err != nil {
			return err
		}
		backup[lockfile] = backupName
		ebin, err := project.MarshalLockEntries(projectLocks, packageLocks)
		if err != nil {
			return err
		}
		jirix.Logger.Debugf("updated lockfile %q", lockfile)
		return os.WriteFile(lockfile, ebin, info.Mode())
	}
	jirix.Logger.Debugf("skipped lockfile %q, no matching projects", lockfile)
	return nil
}

func updateRevision(manifestContent, tag, currentRevision, newRevision, name string) (string, error) {
	// We can do a trivial string replace if the `currentRevision` is non-empty
	// and unique. Otherwise we need to edit the entire XML block for the project.
	if currentRevision != "" && currentRevision != "HEAD" && strings.Count(manifestContent, currentRevision) == 1 {
		return strings.Replace(manifestContent, currentRevision, newRevision, 1), nil
	}
	return updateRevisionOrVersionAttr(manifestContent, tag, newRevision, name, "revision")
}

func updateVersion(manifestContent, tag string, pc packageChanges) (string, error) {
	// There are chances multiple packages share the same version tag,
	// therefore, we cannot simple replace version string globally.
	// Unlike project declaration, the version attribute of a package is not
	// allowed to be empty.
	name := regexp.QuoteMeta(pc.Name)
	oldVal := regexp.QuoteMeta(pc.OldVer)
	// Avoid using %q in regex, it behaves differently from regex.QuoteMeta.
	r, err := regexp.Compile(fmt.Sprintf("( *?)<%s[\\s\\n]+[^<]*?name=\"%s\"(.|\\n)*?version=\"%s\"(.|\\n)*?\\/>", tag, name, oldVal))
	if err != nil {
		return "", err
	}
	t := r.FindStringSubmatch(manifestContent)
	if t == nil {
		return "", fmt.Errorf("Not able to match %s \"%s\"", tag, name)
	}
	s := t[0]
	us := strings.Replace(s, fmt.Sprintf("version=\"%s\"", pc.OldVer), fmt.Sprintf("version=\"%s\"", pc.NewVer), 1)
	return strings.Replace(manifestContent, s, us, 1), nil
}

func updateRevisionOrVersionAttr(manifestContent, tag, newAttrValue, name, attr string) (string, error) {
	// Find the manifest fragment with the appropriate `name`.
	name = regexp.QuoteMeta(name)
	// Avoid using %q in regex, it behaves differently from regex.QuoteMeta.
	r, err := regexp.Compile(fmt.Sprintf("( *?)<%s[\\s\\n]+[^<]*?name=\"%s\"(.|\\n)*?\\/>", tag, name))
	if err != nil {
		return "", err
	}
	t := r.FindStringSubmatch(manifestContent)
	if t == nil {
		return "", fmt.Errorf("Not able to match %s \"%s\"", tag, name)
	}
	s := t[0]
	spaces := t[1]
	for i := 0; i < len(tag); i++ {
		spaces = spaces + " "
	}

	// Try to find the attribute `attr` in the fragment.
	r, err = regexp.Compile(fmt.Sprintf(`%s\s*=\s*"[^"]*"`, attr))
	if err != nil {
		return "", fmt.Errorf("error parsing attr regexp for: %v: %w", attr, err)
	}

	t = r.FindStringSubmatch(s)
	var rs string
	if len(t) == 0 {
		// No such attribute, add it.
		rs = strings.Replace(s, "/>", fmt.Sprintf("\n%s  %s=%q/>", spaces, attr, newAttrValue), 1)
	} else {
		// There is such an attribute, replace it.
		rs = strings.Replace(s, t[0], fmt.Sprintf(`%s="%s"`, attr, newAttrValue), 1)
	}
	// Replace entire original string s with the replacement string.
	return strings.Replace(manifestContent, s, rs, 1), nil
}

func updateManifest(jirix *jiri.X, manifestPath string, projects, imports, packages map[string]string) error {
	ec := &editChanges{
		Projects: []projectChanges{},
		Imports:  []importChanges{},
		Packages: []packageChanges{},
	}

	m, err := project.ManifestFromFile(jirix, manifestPath)
	if err != nil {
		return err
	}
	content, err := os.ReadFile(manifestPath)
	if err != nil {
		return err
	}
	manifestContent := string(content)
	editedProjects := make(map[string]string)
	scm := gitutil.New(jirix, gitutil.RootDirOpt(filepath.Dir(manifestPath)))
	for _, p := range m.Projects {
		newRevision := ""
		if rev, ok := projects[p.Name]; !ok {
			continue
		} else {
			newRevision = rev
		}
		if newRevision == "" {
			branch := "master"
			if p.RemoteBranch != "" {
				branch = p.RemoteBranch
			}
			out, err := scm.LsRemote(p.Remote, fmt.Sprintf("refs/heads/%s", branch))
			if err != nil {
				return err
			}
			newRevision = strings.Fields(string(out))[0]
		}
		if p.Revision == newRevision {
			continue
		}
		if editFlags.editMode == manifest || editFlags.editMode == both {
			manifestContent, err = updateRevision(manifestContent, "project", p.Revision, newRevision, p.Name)
			if err != nil {
				return err
			}
		}
		editedProjects[p.Key().String()] = newRevision
		ec.Projects = append(ec.Projects, projectChanges{
			Name:   p.Name,
			Remote: p.Remote,
			Path:   p.Path,
			OldRev: p.Revision,
			NewRev: newRevision,
		})
	}

	for _, i := range m.Imports {
		newRevision := ""
		if rev, ok := imports[i.Name]; !ok {
			continue
		} else {
			newRevision = rev
		}
		if newRevision == "" {
			branch := "master"
			if i.RemoteBranch != "" {
				branch = i.RemoteBranch
			}
			out, err := scm.LsRemote(i.Remote, fmt.Sprintf("refs/heads/%s", branch))
			if err != nil {
				return err
			}
			newRevision = strings.Fields(string(out))[0]
		}
		if i.Revision == newRevision {
			continue
		}
		manifestContent, err = updateRevision(manifestContent, "import", i.Revision, newRevision, i.Name)
		if err != nil {
			return err
		}
		ec.Imports = append(ec.Imports, importChanges{
			Name:   i.Name,
			Remote: i.Remote,
			OldRev: i.Revision,
			NewRev: newRevision,
		})
	}

	for _, p := range m.Packages {
		newVersion := ""
		if ver, ok := packages[p.Name]; !ok {
			continue
		} else {
			newVersion = ver
		}
		if newVersion == "" || p.Version == newVersion {
			continue
		}
		pc := packageChanges{
			Name:   p.Name,
			OldVer: p.Version,
			NewVer: newVersion,
		}
		manifestContent, err = updateVersion(manifestContent, "package", pc)
		if err != nil {
			return err
		}
		ec.Packages = append(ec.Packages, pc)
	}
	if editFlags.jsonOutput != "" {
		if err := ec.toFile(editFlags.jsonOutput); err != nil {
			return err
		}
	}

	return writeManifest(jirix, manifestPath, manifestContent, editedProjects)
}
