// 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"
	"time"

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

var (
	gcFlag               bool
	localManifestFlag    bool
	attemptsFlag         uint
	autoupdateFlag       bool
	forceAutoupdateFlag  bool
	rebaseUntrackedFlag  bool
	hookTimeoutFlag      uint
	fetchPkgsTimeoutFlag uint
	rebaseAllFlag        bool
	rebaseCurrentFlag    bool
	rebaseSubmodulesFlag bool
	rebaseTrackedFlag    bool
	runHooksFlag         bool
	fetchPkgsFlag        bool
	overrideOptionalFlag bool
	packagesToSkipFlag   arrayFlag
)

const (
	MIN_EXECUTION_TIMING_THRESHOLD time.Duration = time.Duration(30) * time.Minute        // 30 min
	MAX_EXECUTION_TIMING_THRESHOLD time.Duration = time.Duration(2) * time.Hour * 24 * 14 // 2 weeks
)

func init() {
	cmdUpdate.Flags.BoolVar(&gcFlag, "gc", true, "Garbage collect obsolete repositories.")
	cmdUpdate.Flags.BoolVar(&localManifestFlag, "local-manifest", false, "Use local manifest")
	cmdUpdate.Flags.UintVar(&attemptsFlag, "attempts", 3, "Number of attempts before failing.")
	cmdUpdate.Flags.BoolVar(&autoupdateFlag, "autoupdate", true, "Automatically update to the new version.")
	cmdUpdate.Flags.BoolVar(&forceAutoupdateFlag, "force-autoupdate", false, "Always update to the current version.")
	cmdUpdate.Flags.BoolVar(&rebaseUntrackedFlag, "rebase-untracked", false, "Rebase untracked branches onto HEAD.")
	cmdUpdate.Flags.UintVar(&hookTimeoutFlag, "hook-timeout", project.DefaultHookTimeout, "Timeout in minutes for running the hooks operation.")
	cmdUpdate.Flags.UintVar(&fetchPkgsTimeoutFlag, "fetch-packages-timeout", project.DefaultPackageTimeout, "Timeout in minutes for fetching prebuilt packages using cipd.")
	cmdUpdate.Flags.BoolVar(&rebaseAllFlag, "rebase-all", false, "Rebase all tracked branches. Also rebase all untracked branches if -rebase-untracked is passed")
	cmdUpdate.Flags.BoolVar(&rebaseCurrentFlag, "rebase-current", false, "Deprecated. Implies -rebase-tracked. Would be removed in future.")
	cmdUpdate.Flags.BoolVar(&rebaseSubmodulesFlag, "rebase-submodules", false, "Rebase current tracked branches for submodules.")
	cmdUpdate.Flags.BoolVar(&rebaseTrackedFlag, "rebase-tracked", false, "Rebase current tracked branches instead of fast-forwarding them.")
	cmdUpdate.Flags.BoolVar(&runHooksFlag, "run-hooks", true, "Run hooks after updating sources.")
	cmdUpdate.Flags.BoolVar(&fetchPkgsFlag, "fetch-packages", true, "Use cipd to fetch packages.")
	cmdUpdate.Flags.BoolVar(&overrideOptionalFlag, "override-optional", false, "Override existing optional attributes in the snapshot file with current jiri settings")
	cmdUpdate.Flags.Var(&packagesToSkipFlag, "package-to-skip", "Skip fetching this package. Repeatable.")
}

// cmdUpdate represents the "jiri update" command.
var cmdUpdate = &cmdline.Command{
	Runner: jiri.RunnerFunc(runUpdate),
	Name:   "update",
	Short:  "Update all jiri projects",
	Long: `
Updates all projects. The sequence in which the individual updates happen
guarantees that we end up with a consistent workspace. The set of projects
to update is described in the manifest.

Run "jiri help manifest" for details on manifests.
`,
	ArgsName: "<file or url>",
	ArgsLong: "<file or url> points to snapshot to checkout.",
}

func runUpdate(jirix *jiri.X, args []string) error {
	if len(args) > 1 {
		return jirix.UsageErrorf("unexpected number of arguments")
	}

	if attemptsFlag < 1 {
		return jirix.UsageErrorf("Number of attempts should be >= 1")
	}
	jirix.Attempts = attemptsFlag

	if autoupdateFlag {
		// Try to update Jiri itself.
		if err := retry.Function(jirix, func() error {
			return jiri.UpdateAndExecute(forceAutoupdateFlag)
		}, fmt.Sprintf("download jiri binary"), retry.AttemptsOpt(jirix.Attempts)); err != nil {
			fmt.Printf("warning: automatic update failed: %v\n", err)
		}
	}
	if rebaseCurrentFlag {
		jirix.Logger.Warningf("Flag -rebase-current has been deprecated, please use -rebase-tracked.\n\n")
		rebaseTrackedFlag = true
	}

	if len(args) > 0 {
		jirix.OverrideOptional = overrideOptionalFlag
		if err := project.CheckoutSnapshot(jirix, args[0], gcFlag, runHooksFlag, fetchPkgsFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag, packagesToSkipFlag); err != nil {
			return err
		}
	} else {
		lastSnapshot := jirix.UpdateHistoryLatestLink()
		duration := time.Duration(0)
		if info, err := os.Stat(lastSnapshot); err == nil {
			duration = time.Since(info.ModTime())
			if duration < MIN_EXECUTION_TIMING_THRESHOLD || duration > MAX_EXECUTION_TIMING_THRESHOLD {
				duration = time.Duration(0)
			}
		}

		err := project.UpdateUniverse(jirix, gcFlag, localManifestFlag,
			rebaseTrackedFlag, rebaseUntrackedFlag, rebaseAllFlag, runHooksFlag, fetchPkgsFlag, rebaseSubmodulesFlag, hookTimeoutFlag, fetchPkgsTimeoutFlag, packagesToSkipFlag)
		if err2 := project.WriteUpdateHistorySnapshot(jirix, nil, nil, localManifestFlag); err2 != nil {
			if err != nil {
				return fmt.Errorf("while updating: %s, while writing history: %s", err, err2)
			}
			return fmt.Errorf("while writing history: %s", err2)
		}
		if err != nil {
			return err
		}

		// Only track on successful update
		if duration.Nanoseconds() > 0 {
			jirix.AnalyticsSession.AddCommandExecutionTiming("update", duration)
		}
	}

	if jirix.Failures() != 0 {
		return fmt.Errorf("Project update completed with non-fatal errors")
	}

	if err := project.WriteUpdateHistoryLog(jirix); err != nil {
		jirix.Logger.Errorf("Failed to save jiri logs: %v", err)
	}
	return nil
}
