// Copyright 2019 The Chromium 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 omaha

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/maruel/subcommands"
	"go.chromium.org/luci/auth/client/authcli"
	"go.chromium.org/luci/common/cli"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"

	"infra/cmd/stable_version2/internal/cmd"
	gslib "infra/cmd/stable_version2/internal/gs"
	"infra/cmd/stable_version2/internal/site"
	"infra/cmd/stable_version2/internal/utils"
	svlib "infra/cros/stableversion"
	gitlib "infra/libs/git"

	sv "go.chromium.org/chromiumos/infra/proto/go/lab_platform"

	"infra/cmd/stable_version2/internal/cmd/validateconfig/querygs"
)

// UpdateWithOmaha subcommand: read stable version in omaha json file in GS.
var UpdateWithOmaha = &subcommands.Command{
	UsageLine: `update-with-omaha [FLAGS...] -output_json /path/to/output.json`,
	ShortDesc: "update stable version with omaha files",
	LongDesc: `update stable vesrion with omaha json file in GS.

This command is for builder to get up-to-date stable version from omaha file in GS,
and commit them to stable version config file.
Do not use this command as part of scripts or pipelines as it's unstable.

Output is JSON encoded protobuf defined at
https://chromium.googlesource.com/chromiumos/infra/proto/+/refs/heads/main/src/lab_platform/stable_version.proto`,
	CommandRun: func() subcommands.CommandRun {
		c := &updateWithOmahaRun{}
		c.authFlags.Register(&c.Flags, site.DefaultAuthOptions)
		c.Flags.StringVar(&c.outputPath, "output_json", "", "Path where JSON encoded lab_platform.StableVersions should be written.")
		c.Flags.BoolVar(&c.dryRun, "dryrun", false, "indicate if it's a dryrun for stable version update")

		return c
	},
}

type updateWithOmahaRun struct {
	subcommands.CommandRunBase
	authFlags authcli.Flags

	outputPath string
	dryRun     bool
}

// Run implements the subcommands.CommandRun interface.
func (c *updateWithOmahaRun) Run(a subcommands.Application, args []string, env subcommands.Env) int {
	if err := c.innerRun(a, args, env); err != nil {
		cmd.PrintError(a.GetErr(), err)
		return 1
	}
	return 0
}

func (c *updateWithOmahaRun) innerRun(a subcommands.Application, args []string, env subcommands.Env) error {
	ctx := cli.GetContext(a, c, env)
	ctx = cmd.SetupLogging(ctx)
	f := &c.authFlags

	outDir, err := ioutil.TempDir("", cmd.ProgramName)
	if err != nil {
		return err
	}
	defer func() {
		if err := os.RemoveAll(outDir); err != nil {
			logging.Errorf(ctx, "fail to remove temp dir: %s", err)
		}
	}()

	t, err := cmd.NewAuthenticatedTransport(ctx, f)
	if err != nil {
		return errors.Annotate(err, "create authenticated transport").Err()
	}
	var gsc gslibClient
	var gscImpl gslib.Client
	if err := gscImpl.Init(ctx, t, utils.Unmarshaller); err != nil {
		return err
	}
	gsc = &gscImpl

	// Fetch up-to-date stable version based on omaha file
	newCrosSV, err := getGSCrosSV(ctx, outDir, gsc)
	if err != nil {
		return err
	}

	// Fetch existing stable version
	hc, err := cmd.NewHTTPClient(ctx, f)
	if err != nil {
		return err
	}
	gc, err := gitlib.NewClient(ctx, hc, cmd.GerritHost, cmd.GitilesHost, cmd.Project, cmd.Branch)
	if err != nil {
		return err
	}

	oldSV, err := getGitSV(ctx, gc)
	logInvalidCrosSV(ctx, oldSV.GetCros())
	if err != nil {
		return err
	}

	fvFunc := MakeFirmwareVersionFunc(gsc, outDir)
	newSV, err := FileBuilder(ctx, oldSV, newCrosSV, fvFunc)
	if err != nil {
		return err
	}

	validateErr := validateFile(ctx, a, t, newSV)

	if c.dryRun {
		content, err := svlib.WriteSVToString(newSV)
		if err == nil {
			fmt.Printf("%s\n", content)
		}
		if validateErr != nil {
			return validateErr
		}
		if err != nil {
			return err
		}
		return nil
	}

	if validateErr != nil {
		return validateErr
	}

	changeURL, err := commitNew(ctx, gc, newSV)
	if err != nil {
		return err
	}
	logging.Debugf(ctx, "Update stable version CL: %s", changeURL)
	return nil
}

func validateFile(ctx context.Context, a subcommands.Application, t http.RoundTripper, newSV *sv.StableVersions) error {
	// validate config before committing it
	var r querygs.Reader
	if err := r.Init(ctx, t, utils.Unmarshaller, "validate-config"); err != nil {
		return fmt.Errorf("initializing Google Storage client: %s", err)
	}

	res, err := r.ValidateConfig(ctx, newSV)
	if err != nil {
		return fmt.Errorf("valdating config using Google Storage: %s", err)
	}
	res.RemoveAllowedDUTs()
	msg, err := json.MarshalIndent(res, "", "    ")
	if err != nil {
		panic("failed to marshal JSON")
	}

	if count := res.AnomalyCount(); count > 0 {
		fmt.Fprintf(a.GetErr(), "%s\n", msg)
		return fmt.Errorf("(%d) errors detected: %s", count, msg)
	}

	return nil
}

// Get CrOS stable version from omaha status file.
func getGSCrosSV(ctx context.Context, outDir string, gsc gslibClient) ([]*sv.StableCrosVersion, error) {
	localOSFile := filepath.Join(outDir, cmd.OmahaStatusFile)
	if err := gsc.Download(cmd.OmahaGSPath, localOSFile); err != nil {
		return nil, err
	}
	omahaBytes, err := ioutil.ReadFile(localOSFile)
	if err != nil {
		return nil, errors.Annotate(err, "load omaha").Err()
	}
	cros, err := gslib.ParseOmahaStatus(ctx, omahaBytes)
	if err != nil {
		return nil, errors.Annotate(err, "parse omaha").Err()
	}
	return cros, nil
}

// getGitSV gets stable versions from the git client.
func getGitSV(ctx context.Context, gc *gitlib.Client) (*sv.StableVersions, error) {
	res, err := gc.GetFile(ctx, cmd.StableVersionConfigPath)
	if err != nil {
		return nil, err
	}
	if res == "" {
		logging.Warningf(ctx, "empty stable version config file: %s", cmd.StableVersionConfigPath)
		return nil, err
	}
	var allSV sv.StableVersions
	if err := utils.Unmarshaller.Unmarshal(strings.NewReader(res), &allSV); err != nil {
		return nil, err
	}
	return &allSV, nil
}

func logInvalidCrosSV(ctx context.Context, crosSV []*sv.StableCrosVersion) {
	for _, csv := range crosSV {
		if err := svlib.ValidateCrOSVersion(csv.GetVersion()); err != nil {
			logging.Debugf(ctx, "invalid cros version: %s, %s", csv.GetKey().GetBuildTarget().GetName(), csv.GetVersion())
		}
	}
}

func commitNew(ctx context.Context, gc *gitlib.Client, sv *sv.StableVersions) (string, error) {
	newContent, err := svlib.WriteSVToString(sv)
	if err != nil {
		return "", errors.Annotate(err, "convert change").Err()
	}

	u := map[string]string{
		cmd.StableVersionConfigPath: newContent,
	}
	changeInfo, err := gc.UpdateFiles(ctx, "Update stable version (automatically)", u)
	if err != nil {
		return "", errors.Annotate(err, "update change").Err()
	}
	gerritURL, err := gc.SubmitChange(ctx, changeInfo)
	if err != nil {
		return "", errors.Annotate(err, "submit change").Err()
	}
	return gerritURL, nil
}

func localMetaFilePath(crosSV *sv.StableCrosVersion) string {
	return fmt.Sprintf("%s-%s", crosSV.GetKey().GetBuildTarget().GetName(), crosSV.GetVersion())
}
