// 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"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"time"

	"v.io/jiri/collect"
	"v.io/jiri/gitutil"
	"v.io/jiri/jiri"
	"v.io/jiri/project"
	"v.io/x/lib/cmdline"
)

var (
	remoteFlag     bool
	timeFormatFlag string
)

func init() {
	cmdSnapshot.Flags.BoolVar(&remoteFlag, "remote", false, "Manage remote snapshots.")
	cmdSnapshotCreate.Flags.StringVar(&timeFormatFlag, "time-format", time.RFC3339, "Time format for snapshot file name.")
}

var cmdSnapshot = &cmdline.Command{
	Name:  "snapshot",
	Short: "Manage project snapshots",
	Long: `
The "jiri snapshot" command can be used to manage project snapshots.
In particular, it can be used to create new snapshots and to list
existing snapshots.

The command-line flag "-remote" determines whether the command
pertains to "local" snapshots that are only stored locally or "remote"
snapshots the are revisioned in the manifest repository.
`,
	Children: []*cmdline.Command{cmdSnapshotCreate, cmdSnapshotList},
}

// cmdSnapshotCreate represents the "jiri snapshot create" command.
var cmdSnapshotCreate = &cmdline.Command{
	Runner: jiri.RunnerFunc(runSnapshotCreate),
	Name:   "create",
	Short:  "Create a new project snapshot",
	Long: `
The "jiri snapshot create <label>" command captures the current project
state in a manifest and, depending on the value of the -remote flag,
the command either stores the manifest in the local
$JIRI_ROOT/.snapshots directory, or in the manifest repository, pushing
the change to the remote repository and thus making it available
globally.

Internally, snapshots are organized as follows:

 <snapshot-dir>/
   labels/
     <label1>/
       <label1-snapshot1>
       <label1-snapshot2>
       ...
     <label2>/
       <label2-snapshot1>
       <label2-snapshot2>
       ...
     <label3>/
     ...
   <label1> # a symlink to the latest <label1-snapshot*>
   <label2> # a symlink to the latest <label2-snapshot*>
   ...

NOTE: Unlike the jiri tool commands, the above internal organization
is not an API. It is an implementation and can change without notice.
`,
	ArgsName: "<label>",
	ArgsLong: "<label> is the snapshot label.",
}

func runSnapshotCreate(jirix *jiri.X, args []string) error {
	if len(args) != 1 {
		return jirix.UsageErrorf("unexpected number of arguments")
	}
	label := args[0]
	if err := checkSnapshotDir(jirix); err != nil {
		return err
	}
	snapshotDir, err := getSnapshotDir()
	if err != nil {
		return err
	}
	snapshotFile := filepath.Join(snapshotDir, "labels", label, time.Now().Format(timeFormatFlag))
	// Either atomically create a new snapshot that captures the project
	// state and push the changes to the remote repository (if
	// applicable), or fail with no effect.
	createFn := func() error {
		revision, err := jirix.Git().CurrentRevision()
		if err != nil {
			return err
		}
		if err := createSnapshot(jirix, snapshotDir, snapshotFile, label); err != nil {
			// Clean up on all errors.
			jirix.Git().Reset(revision)
			jirix.Git().RemoveUntrackedFiles()
			return err
		}
		return nil
	}

	// Execute the above function in the snapshot directory.
	p := project.Project{
		Path:     snapshotDir,
		Protocol: "git",
		Revision: "HEAD",
	}
	if err := project.ApplyToLocalMaster(jirix, project.Projects{p.Name: p}, createFn); err != nil {
		return err
	}
	return nil
}

// checkSnapshotDir makes sure that he local snapshot directory exists
// and is initialized properly.
func checkSnapshotDir(jirix *jiri.X) (e error) {
	snapshotDir, err := getSnapshotDir()
	if err != nil {
		return err
	}
	if _, err := jirix.Run().Stat(snapshotDir); err != nil {
		if !os.IsNotExist(err) {
			return err
		}
		if remoteFlag {
			if err := jirix.Run().MkdirAll(snapshotDir, 0755); err != nil {
				return err
			}
			return nil
		}
		createFn := func() (err error) {
			if err := jirix.Run().MkdirAll(snapshotDir, 0755); err != nil {
				return err
			}
			if err := jirix.Git().Init(snapshotDir); err != nil {
				return err
			}
			cwd, err := os.Getwd()
			if err != nil {
				return err
			}
			defer collect.Error(func() error { return jirix.Run().Chdir(cwd) }, &e)
			if err := jirix.Run().Chdir(snapshotDir); err != nil {
				return err
			}
			if err := jirix.Git().Commit(); err != nil {
				return err
			}
			return nil
		}
		if err := createFn(); err != nil {
			jirix.Run().RemoveAll(snapshotDir)
			return err
		}
	}
	return nil
}

func createSnapshot(jirix *jiri.X, snapshotDir, snapshotFile, label string) error {
	// Create a snapshot that encodes the current state of master
	// branches for all local projects.
	if err := project.CreateSnapshot(jirix, snapshotFile); err != nil {
		return err
	}

	// Update the symlink for this snapshot label to point to the
	// latest snapshot.
	symlink := filepath.Join(snapshotDir, label)
	newSymlink := symlink + ".new"
	if err := jirix.Run().RemoveAll(newSymlink); err != nil {
		return err
	}
	relativeSnapshotPath := strings.TrimPrefix(snapshotFile, snapshotDir+string(os.PathSeparator))
	if err := jirix.Run().Symlink(relativeSnapshotPath, newSymlink); err != nil {
		return err
	}
	if err := jirix.Run().Rename(newSymlink, symlink); err != nil {
		return err
	}

	// Revision the changes.
	if err := revisionChanges(jirix, snapshotDir, snapshotFile, label); err != nil {
		return err
	}
	return nil
}

// getSnapshotDir returns the path to the snapshot directory,
// respecting the value of the "-remote" command-line flag.
func getSnapshotDir() (string, error) {
	if remoteFlag {
		snapshotDir, err := project.RemoteSnapshotDir()
		if err != nil {
			return "", err
		}
		return snapshotDir, nil
	}
	snapshotDir, err := project.LocalSnapshotDir()
	if err != nil {
		return "", err
	}
	return snapshotDir, nil
}

// revisionChanges commits changes identified by the given manifest
// file and label to the manifest repository and (if applicable)
// pushes these changes to the remote repository.
func revisionChanges(jirix *jiri.X, snapshotDir, snapshotFile, label string) (e error) {
	cwd, err := os.Getwd()
	if err != nil {
		return err
	}
	defer collect.Error(func() error { return jirix.Run().Chdir(cwd) }, &e)
	if err := jirix.Run().Chdir(snapshotDir); err != nil {
		return err
	}
	relativeSnapshotPath := strings.TrimPrefix(snapshotFile, snapshotDir+string(os.PathSeparator))
	if err := jirix.Git().Add(relativeSnapshotPath); err != nil {
		return err
	}
	if err := jirix.Git().Add(label); err != nil {
		return err
	}
	name := strings.TrimPrefix(snapshotFile, snapshotDir)
	if err := jirix.Git().CommitWithMessage(fmt.Sprintf("adding snapshot %q for label %q", name, label)); err != nil {
		return err
	}
	if remoteFlag {
		if err := jirix.Git().Push("origin", "master", gitutil.VerifyOpt(false)); err != nil {
			return err
		}
	}
	return nil
}

// cmdSnapshotList represents the "jiri snapshot list" command.
var cmdSnapshotList = &cmdline.Command{
	Runner: jiri.RunnerFunc(runSnapshotList),
	Name:   "list",
	Short:  "List existing project snapshots",
	Long: `
The "snapshot list" command lists existing snapshots of the labels
specified as command-line arguments. If no arguments are provided, the
command lists snapshots for all known labels.
`,
	ArgsName: "<label ...>",
	ArgsLong: "<label ...> is a list of snapshot labels.",
}

func runSnapshotList(jirix *jiri.X, args []string) error {
	if err := checkSnapshotDir(jirix); err != nil {
		return err
	}

	snapshotDir, err := getSnapshotDir()
	if err != nil {
		return err
	}
	if len(args) == 0 {
		// Identify all known snapshot labels, using a
		// heuristic that looks for all symbolic links <foo>
		// in the snapshot directory that point to a file in
		// the "labels/<foo>" subdirectory of the snapshot
		// directory.
		fileInfoList, err := ioutil.ReadDir(snapshotDir)
		if err != nil {
			return fmt.Errorf("ReadDir(%v) failed: %v", snapshotDir, err)
		}
		for _, fileInfo := range fileInfoList {
			if fileInfo.Mode()&os.ModeSymlink != 0 {
				path := filepath.Join(snapshotDir, fileInfo.Name())
				dst, err := filepath.EvalSymlinks(path)
				if err != nil {
					return fmt.Errorf("EvalSymlinks(%v) failed: %v", path, err)
				}
				if strings.HasSuffix(filepath.Dir(dst), filepath.Join("labels", fileInfo.Name())) {
					args = append(args, fileInfo.Name())
				}
			}
		}
	}

	// Check that all labels exist.
	failed := false
	for _, label := range args {
		labelDir := filepath.Join(snapshotDir, "labels", label)
		if _, err := jirix.Run().Stat(labelDir); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
			failed = true
			fmt.Fprintf(jirix.Stderr(), "snapshot label %q not found", label)
		}
	}
	if failed {
		return cmdline.ErrExitCode(2)
	}

	// Print snapshots for all labels.
	sort.Strings(args)
	for _, label := range args {
		// Scan the snapshot directory "labels/<label>" printing
		// all snapshots.
		labelDir := filepath.Join(snapshotDir, "labels", label)
		fileInfoList, err := ioutil.ReadDir(labelDir)
		if err != nil {
			return fmt.Errorf("ReadDir(%v) failed: %v", labelDir, err)
		}
		fmt.Fprintf(jirix.Stdout(), "snapshots of label %q:\n", label)
		for _, fileInfo := range fileInfoList {
			fmt.Fprintf(jirix.Stdout(), "  %v\n", fileInfo.Name())
		}
	}
	return nil
}
