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

import (
	"fmt"
	"os"
	"path/filepath"

	"v.io/jiri/jiri"
	"v.io/jiri/project"
	"v.io/jiri/runutil"
	"v.io/x/lib/cmdline"
)

// TODO(toddw): Remove the upgrade command after the transition to new-style
// manifests is complete.

var flagUpgradeRevert bool

func init() {
	cmdUpgrade.Flags.BoolVar(&flagUpgradeRevert, "revert", false, `Revert the upgrade by deleting the $JIRI_ROOT/.jiri_manifest file.`)
}

var cmdUpgrade = &cmdline.Command{
	Runner: jiri.RunnerFunc(runUpgrade),
	Name:   "upgrade",
	Short:  "Upgrade jiri to new-style manifests",
	Long: `
Upgrades jiri to use new-style manifests.

The old (deprecated) behavior only allowed a single manifest repository, located
in $JIRI_ROOT/.manifest.  The initial manifest file is located as follows:
  1) Use -manifest flag, if non-empty.  If it's empty...
  2) Use $JIRI_ROOT/.local_manifest file.  If it doesn't exist...
  3) Use $JIRI_ROOT/.manifest/v2/default.

The new behavior allows multiple manifest repositories, by allowing imports to
specify project attributes describing the remote repository.  The -manifest flag
is no longer allowed to be set; the initial manifest file is always located in
$JIRI_ROOT/.jiri_manifest.  The .local_manifest file is ignored.

During the transition phase, both old and new behaviors are supported.  The jiri
tool uses the existence of the $JIRI_ROOT/.jiri_manifest file as the signal; if
it exists we run the new behavior, otherwise we run the old behavior.

The new behavior includes a "jiri import" command, which writes or updates the
.jiri_manifest file.  The new bootstrap procedure runs "jiri import", and it is
intended as a regular command to add imports to your jiri environment.

This upgrade command eases the transition by writing an initial .jiri_manifest
file for you.  If you have an existing .local_manifest file, its contents will
be incorporated into the new .jiri_manifest file, and it will be renamed to
.local_manifest.BACKUP.  The -revert flag deletes the .jiri_manifest file, and
restores the .local_manifest file.
`,
	ArgsName: "<kind>",
	ArgsLong: `
<kind> specifies the kind of upgrade, one of "v23" or "fuchsia".
`,
}

func runUpgrade(jirix *jiri.X, args []string) error {
	localFile := filepath.Join(jirix.Root, ".local_manifest")
	backupFile := localFile + ".BACKUP"
	if flagUpgradeRevert {
		// Restore .local_manifest.BACKUP if it exists.
		switch _, err := jirix.NewSeq().Stat(backupFile); {
		case err != nil && !runutil.IsNotExist(err):
			return err
		case err == nil:
			if err := jirix.NewSeq().Rename(backupFile, localFile).Done(); err != nil {
				return fmt.Errorf("couldn't restore %v to %v: %v", backupFile, localFile, err)
			}
		}
		// Deleting the .jiri_manifest file reverts to the old behavior.
		return jirix.NewSeq().Remove(jirix.JiriManifestFile()).Done()
	}
	if len(args) != 1 {
		return jirix.UsageErrorf("must specify upgrade kind")
	}
	kind := args[0]
	var argRemote, argName, argManifest string
	switch kind {
	case "v23":
		argRemote = "https://vanadium.googlesource.com/manifest"
		argName, argManifest = "manifest", "public"
	case "fuchsia":
		argRemote = "https://github.com/effenel/fnl-start.git"
		argName, argManifest = "fnl-start", "manifest/fuchsia"
	default:
		return jirix.UsageErrorf("unknown upgrade kind %q", kind)
	}
	// Initialize manifest from .local_manifest.
	hasLocalFile := true
	manifest, err := project.ManifestFromFile(jirix, localFile)
	if err != nil {
		if !runutil.IsNotExist(err) {
			return err
		}
		hasLocalFile = false
		manifest = &project.Manifest{}
	}
	oldImports := manifest.Imports
	manifest.Imports = nil
	for _, oldImport := range oldImports {
		if oldImport.Remote != "" {
			// This is a new-style remote import, carry it over directly.
			manifest.Imports = append(manifest.Imports, oldImport)
			continue
		}
		// This is an old-style import, convert it to the new style.
		oldName := oldImport.Name
		switch {
		case kind == "v23" && oldName == "default":
			oldName = "public"
		case kind == "fuchsia" && oldName == "default":
			oldName = "manifest/fuchsia"
		}
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: oldName,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	if len(manifest.Imports) == 0 {
		manifest.Imports = append(manifest.Imports, project.Import{
			Manifest: argManifest,
			Name:     argName,
			Remote:   argRemote,
		})
	}
	// Write output to .jiri_manifest file.
	outFile := jirix.JiriManifestFile()
	if _, err := os.Stat(outFile); err == nil {
		return fmt.Errorf("%v already exists", outFile)
	}
	if err := manifest.ToFile(jirix, outFile); err != nil {
		return err
	}
	// Backup .local_manifest file, if it exists.
	if hasLocalFile {
		if err := jirix.NewSeq().Rename(localFile, backupFile).Done(); err != nil {
			return fmt.Errorf("couldn't backup %v to %v: %v", localFile, backupFile, err)
		}
	}
	return nil
}
