// Copyright 2019 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 (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"

	"github.com/golang/protobuf/proto"
	"go.chromium.org/luci/common/retry"
	"go.chromium.org/luci/common/retry/transient"
	"go.fuchsia.dev/infra/checkout"
	rbc "go.fuchsia.dev/infra/cmd/recipe_bootstrap/checkout"
	"go.fuchsia.dev/infra/cmd/recipe_bootstrap/manifest"
	"go.fuchsia.dev/infra/cmd/recipe_bootstrap/props"
	"go.fuchsia.dev/infra/gerrit"
	"go.fuchsia.dev/infra/gitiles"
	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/types/known/structpb"

	"go.chromium.org/luci/auth"
	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
	gerritapi "go.chromium.org/luci/common/api/gerrit"
	gitilesapi "go.chromium.org/luci/common/api/gitiles"
	"go.chromium.org/luci/common/logging"
	"go.chromium.org/luci/common/logging/gologger"
	gerritpb "go.chromium.org/luci/common/proto/gerrit"
	"go.chromium.org/luci/logdog/client/butlerlib/bootstrap"
	"go.chromium.org/luci/logdog/client/butlerlib/streamclient"
	"go.chromium.org/luci/luciexe"
)

const (
	// Fallback ref to fetch, when build has no input, e.g. when the build is manually
	// triggered with LUCI scheduler, or when the recipes_host_override property is set.
	fallbackRef = "refs/heads/main"

	// Default integration.git remote, for when build has no input, e.g. when
	// the build is manually triggered with LUCI scheduler.
	defaultIntegrationRemote = "https://fuchsia.googlesource.com/integration"

	// Recipe manifest filename relative to root of an integration checkout.
	recipesManifest = "infra/recipes"

	// Recipes.git remote.
	recipesRemote = "https://fuchsia.googlesource.com/infra/recipes"

	// Default timeout for checkout operations.
	defaultCheckoutTimeout = 5 * time.Minute
)

// resolveRef returns a resolved sha1 from a ref e.g. refs/heads/main.
func resolveRef(ctx context.Context, host, project, ref string) (string, error) {
	authClient, err := auth.NewAuthenticator(ctx, auth.SilentLogin, auth.Options{Scopes: []string{gitilesapi.OAuthScope}}).Client()
	if err != nil {
		return "", fmt.Errorf("could not initialize auth client: %w", err)
	}
	client, err := gitiles.NewClient(ctx, host, project, authClient)
	if err != nil {
		return "", fmt.Errorf("could not initialize gitiles client: %w", err)
	}
	return client.LatestCommit(ctx, ref)
}

// resolveGitilesRef returns the ref associated with the build's input.
//
// If the build input has a GitilesCommit, return GitilesCommit.Ref.
//
// If the build input only has a GerritChange, query change info from Gerrit and
// return the ref.
// Note that this is the ref that the change targets i.e. refs/heads/*, not the
// magic change ref, e.g. refs/changes/*.
//
// If the build input has neither, return the fallbackRef.
func resolveGitilesRef(ctx context.Context, buildInput *buildbucketpb.Build_Input, fallbackRef string) (string, error) {
	if buildInput.GitilesCommit != nil {
		return buildInput.GitilesCommit.Ref, nil
	}
	if len(buildInput.GerritChanges) > 0 {
		authClient, err := auth.NewAuthenticator(ctx, auth.SilentLogin, auth.Options{Scopes: []string{gerritapi.OAuthScope}}).Client()
		if err != nil {
			return "", fmt.Errorf("could not initialize auth client: %w", err)
		}
		client, err := gerrit.NewClient(ctx, buildInput.GerritChanges[0].Host, buildInput.GerritChanges[0].Project, authClient)
		if err != nil {
			return "", fmt.Errorf("failed to initialize gerrit client: %w", err)
		}
		// GetChange may sometimes encounter transient failures which should be
		// retried.
		retryPolicy := transient.Only(func() retry.Iterator {
			return &retry.ExponentialBackoff{
				Limited: retry.Limited{
					Delay:   5 * time.Second,
					Retries: 3,
				},
				Multiplier: 1.5,
			}
		})
		var resp *gerritpb.ChangeInfo
		if err := retry.Retry(ctx, retryPolicy, func() error {
			resp, err = client.GetChange(ctx, buildInput.GerritChanges[0].Change)
			return err
		}, nil); err != nil {
			return "", fmt.Errorf("failed to get change info: %w", err)
		}
		return resp.Ref, nil
	}
	return fallbackRef, nil
}

// ensureGitilesCommit ensures that the incoming build always has an
// Input.GitilesCommit. This ensures that this build and any child builds
// always use a consistent HEAD.
//
// The host and project for the GitilesCommit are determined by the
// `ResolveRepo` strategy, with the fallback remote being either the default
// integration remote set in this file, or the override set by the
// `recipe_integration_remote` property.
func ensureGitilesCommit(ctx context.Context, build *buildbucketpb.Build) error {
	if build.Input.GitilesCommit != nil {
		return nil
	}
	fallbackRemote, err := props.GetStringInputProperty(build, "recipe_integration_remote")
	if err != nil {
		return err
	}
	if fallbackRemote == "" {
		fallbackRemote = defaultIntegrationRemote
	}
	host, project, err := rbc.ResolveRepo(build.Input, fallbackRemote)
	if err != nil {
		return fmt.Errorf("failed to resolve host and project: %w", err)
	}
	ref, err := resolveGitilesRef(ctx, build.Input, fallbackRef)
	if err != nil {
		return fmt.Errorf("failed to resolve gitiles ref: %w", err)
	}
	revision, err := resolveRef(ctx, host, project, ref)
	if err != nil {
		return fmt.Errorf("failed to resolve %s HEAD: %v", ref, err)
	}
	build.Input.GitilesCommit = &buildbucketpb.GitilesCommit{
		Host:    host,
		Project: project,
		Id:      revision,
		Ref:     ref,
	}
	return nil
}

// getBuilderFilePath returns the builder file path to read the build input properties.
func getBuilderFilePath(integrationDir string, build *buildbucketpb.Build) string {
	// TODO(fxbug.dev//71232): switch to "builders" directory once all maintained release branches are newer.
	return filepath.Join(
		integrationDir, "infra", "config", "generated", build.Builder.Project,
		"for_review_only", "buildbucket", build.Builder.Bucket,
		fmt.Sprintf("%s.textproto", build.Builder.Builder),
	)
}

// checkoutIntegration checks out the integration.git repo and returns the path
// to the directory containing the checkout.
func checkoutIntegration(ctx context.Context, build *buildbucketpb.Build) (string, error) {
	// Do a checkout in a temporary directory to avoid checkout conflicts with
	// the recipe's working directory.
	cwd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	integrationDir, err := ioutil.TempDir(cwd, "integration-checkout")
	if err != nil {
		return integrationDir, err
	}
	integrationURL, integrationBaseRevision, err := resolveIntegration(ctx, build)
	if err != nil {
		return integrationDir, err
	}
	if err := props.SetInputProperty(build, "integration_base_revision", integrationBaseRevision); err != nil {
		return integrationDir, err
	}
	tctx, cancel := context.WithTimeout(ctx, defaultCheckoutTimeout)
	defer cancel()
	return integrationDir, checkout.Checkout(tctx, build.Input, *integrationURL, integrationBaseRevision, integrationDir)
}

// resolveIntegration resolves the integration URL and revision to checkout.
//
// If the `recipes_host_override` property is specified, then override the
// integration host.
//
// If the `integration_base_revision` property is set, use this revision.
func resolveIntegration(ctx context.Context, build *buildbucketpb.Build) (*url.URL, string, error) {
	recipesHostOverride, err := props.GetStringInputProperty(build, "recipes_host_override")
	if err != nil {
		return nil, "", err
	}
	integrationURL, err := rbc.ResolveIntegrationURL(build.Input, recipesHostOverride)
	if err != nil {
		return nil, "", err
	}

	baseRevisionProperty, err := props.GetStringInputProperty(build, "integration_base_revision")
	if err != nil {
		return nil, "", err
	}
	if baseRevisionProperty != "" {
		// If `integration_base_revision` is set then we're probably running as
		// a subbuild and `integration_base_revision` is the revision resolved
		// by the parent build, so we should use the same revision.
		return integrationURL, baseRevisionProperty, nil
	}

	commit := build.Input.GitilesCommit
	if integrationURL.Host == commit.Host && integrationURL.Path == commit.Project {
		// Either the build was triggered on an integration change and we
		// already resolved a base revision with `ensureGitilesCommit`, or the
		// build was triggered by a specific integration commit.  In either case
		// we want to use that resolved revision to ensure we check out the same
		// version of integration as the recipe.
		return integrationURL, commit.Id, nil
	}

	// Otherwise we haven't yet resolved an integration base revision, so we
	// need to choose the correct integration ref to resolve and then resolve
	// that ref to a revision.

	overrideRef, err := props.GetStringInputProperty(build, "recipes_integration_ref_override")
	if err != nil {
		return nil, "", err
	}
	var ref string
	if overrideRef != "" {
		ref = overrideRef
	} else if commit.Ref != "" {
		// This assumes that for every ref `refs/heads/foo` of every repository
		// pinned in integration that we care about submitting changes to, there
		// exists a corresponding ref `refs/heads/foo` in the integration
		// repository.
		ref = commit.Ref
	} else {
		ref = fallbackRef
	}

	revision, err := resolveRef(ctx, integrationURL.Host, integrationURL.Path, ref)
	if err != nil {
		return nil, "", fmt.Errorf("failed to resolve integration HEAD: %w", err)
	}

	return integrationURL, revision, nil
}

// resolveBuildProperties resolves the build input properties to use.
//
// If enable_property_versioning is set, merge the build input properties with
// integration properties.
func resolveBuildProperties(builderFilePath string, build *buildbucketpb.Build) error {
	enablePropertyVersion, err := props.GetBoolInputProperty(build, "enable_property_versioning")
	if err != nil {
		return err
	}
	// If the enable_property_versioning is not set, we'll use the original input properties.
	if !enablePropertyVersion {
		return nil
	}
	// Make a copy of the original input properties.
	originalProperties := build.Input.Properties.AsMap()
	builderBytes, err := ioutil.ReadFile(builderFilePath)
	if err != nil {
		return fmt.Errorf("failed to read builder file %s: %v", builderFilePath, err)
	}
	// Replace the input properties with the resolved integration.git properties.
	build.Input.Properties, err = builderProperties(builderBytes)
	if err != nil {
		return fmt.Errorf("failed to read builder properties from integration repo: %w", err)
	}
	// Merge the original input properties, which should contain only request properties, into integration.git properties.
	for property, value := range originalProperties {
		if err := props.SetInputProperty(build, property, value); err != nil {
			return fmt.Errorf("failed to set the property %s: %v", property, err)
		}
	}
	return nil
}

// Gets builder properties from buildbucketpb.Bucket bytes data.
func builderProperties(manifestBytes []byte) (*structpb.Struct, error) {
	builderProto := &buildbucketpb.Bucket{}
	if err := prototext.Unmarshal(manifestBytes, builderProto); err != nil {
		return nil, err
	}
	builders := builderProto.GetSwarming().GetBuilders()
	if len(builders) != 1 {
		return nil, fmt.Errorf("expected 1 builder, got %d", len(builders))
	}
	properties := builders[0].GetProperties()
	data := &structpb.Struct{}
	if err := json.Unmarshal([]byte(properties), data); err != nil {
		return nil, err
	}
	return data, nil
}

// checkoutRecipes resolves the recipe version to check out, checks out the recipes
// repo, and returns the path to the checked-out repository.
//
// If the build input has a recipe change, then checkout directly using the
// build input.
//
// Otherwise, checkout at the revision specified by Build.Input.Properties.
func checkoutRecipes(ctx context.Context, integrationDir string, build *buildbucketpb.Build) (string, error) {
	// Do recipes checkout in a temporary directory to avoid checkout conflicts
	// with the recipe's working directory.
	cwd, err := os.Getwd()
	if err != nil {
		return "", fmt.Errorf("failed to get working directory: %w", err)

	}
	recipesDir, err := ioutil.TempDir(cwd, "recipes-checkout")
	if err != nil {
		return recipesDir, fmt.Errorf("failed to get create tempdir: %w", err)

	}
	recipesURL, err := url.Parse(recipesRemote)
	if err != nil {
		return recipesDir, fmt.Errorf("could not parse URL %s", recipesRemote)
	}
	var input *buildbucketpb.Build_Input
	hasRecipeChange, err := rbc.HasRepoChange(build.Input, recipesRemote)
	if err != nil {
		return recipesDir, fmt.Errorf("could not determine whether build input has recipe change: %w", err)
	}
	if hasRecipeChange {
		input = build.Input
	} else {
		// Use the recipe version from the checkout integrationDir.
		manifestXML, err := os.Open(filepath.Join(integrationDir, recipesManifest))
		if err != nil {
			return recipesDir, fmt.Errorf("failed to read recipes manifest file: %s: %v", filepath.Join(integrationDir, recipesManifest), err)
		}
		defer manifestXML.Close()
		proj, err := manifest.ResolveRecipesProject(manifestXML, recipesRemote)
		if err != nil {
			return recipesDir, err
		}
		input = &buildbucketpb.Build_Input{
			GitilesCommit: &buildbucketpb.GitilesCommit{
				Host:    recipesURL.Host,
				Project: strings.TrimLeft(recipesURL.Path, "/"),
				Id:      proj.Revision,
			},
		}
	}
	tctx, cancel := context.WithTimeout(ctx, defaultCheckoutTimeout)
	defer cancel()
	if err := checkout.Checkout(tctx, input, *recipesURL, "", recipesDir); err != nil {
		return recipesDir, fmt.Errorf("failed to checkout: %w", err)
	}
	return recipesDir, nil
}

// fetchRecipeDeps runs `recipes.py fetch`, which checks out all recipe git
// repos that the current recipes repo repends on. `recipes.py luciexe` would
// handle fetching deps even if we didn't run `recipes.py fetch` separately
// beforehand, but running `recipes.py fetch` separately makes it easier to
// distinguish between fetch errors (which are generally caused by transient Git
// server issues) and true build errors within the executed recipe.
func fetchRecipeDeps(ctx context.Context, recipesDir string) error {
	cmd, err := recipeCommand(ctx, recipesDir, "fetch")
	if err != nil {
		return err
	}
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("failed to fetch recipe deps: %w", err)
	}
	return nil
}

// executeRecipe exec's `recipes.py luciexe`, passing build.proto through stdin.
func executeRecipe(ctx context.Context, recipesDir string, build *buildbucketpb.Build, outputPath string) error {
	args := []string{"luciexe"}
	if outputPath != "" {
		args = append(args, "--output", outputPath)
	}
	cmd, err := recipeCommand(ctx, recipesDir, args...)
	if err != nil {
		return err
	}
	inputData, err := proto.Marshal(build)
	if err != nil {
		return fmt.Errorf("could not marshal input build: %w", err)
	}
	cmd.Stdin = bytes.NewBuffer(inputData)
	return cmd.Run()
}

// recipeCommand constructs an exec.Cmd that will run the `recipes.py` script
// found in `recipesDir` with the specified arguments.
func recipeCommand(ctx context.Context, recipesDir string, recipesPyArgs ...string) (*exec.Cmd, error) {
	args := []string{filepath.Join(recipesDir, "recipes.py")}
	args = append(args, recipesPyArgs...)
	python, err := exec.LookPath("python")
	if err != nil {
		return nil, fmt.Errorf("could not find python on PATH: %w", err)
	}
	cmd := exec.CommandContext(ctx, python, args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd, nil
}

// outputBuildSummary outputs error details to the current build's
// summary_markdown in case of failure.
func outputBuildSummary(ctx context.Context, summary string) error {
	bootstrap, err := bootstrap.Get()
	if err != nil {
		return err
	}
	stream, err := bootstrap.Client.NewDatagramStream(
		ctx,
		luciexe.BuildProtoStreamSuffix,
		streamclient.WithContentType(luciexe.BuildProtoContentType),
	)
	if err != nil {
		return err
	}
	build := &buildbucketpb.Build{}
	build.SummaryMarkdown = summary
	build.Status = buildbucketpb.Status_INFRA_FAILURE
	outputData, err := proto.Marshal(build)
	if err != nil {
		return fmt.Errorf("failed to marshal output build.proto: %w", err)
	}
	return stream.WriteDatagram(outputData)
}

// setUpRecipes processes the build input to determine which revision of recipes
// to checkout, then checks out the recipes repo at that revision. It returns
// the deserialized input build.proto along with the path to the recipes
// checkout.
func setUpRecipes(ctx context.Context) (build *buildbucketpb.Build, recipesDir string, err error) {
	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		err = fmt.Errorf("failed to read build.proto from stdin: %w", err)
		return
	}
	build = &buildbucketpb.Build{}
	if err = proto.Unmarshal(data, build); err != nil {
		err = fmt.Errorf("failed to unmarshal build.proto from stdin: %w", err)
		return
	}
	if err = ensureGitilesCommit(ctx, build); err != nil {
		err = fmt.Errorf("failed to ensure that build has a gitiles commit: %w", err)
		return
	}
	integrationDir, err := checkoutIntegration(ctx, build)
	defer os.RemoveAll(integrationDir)
	if err != nil {
		err = fmt.Errorf("failed to checkout integration repo: %w", err)
		return
	}
	if err = resolveBuildProperties(getBuilderFilePath(integrationDir, build), build); err != nil {
		err = fmt.Errorf("failed to resolve the build properties: %w", err)
		return
	}
	recipesDir, err = checkoutRecipes(ctx, integrationDir, build)
	if err != nil {
		err = fmt.Errorf("failed to checkout recipes repo: %w", err)
		return
	}
	if err = fetchRecipeDeps(ctx, recipesDir); err != nil {
		return
	}
	b, err := json.MarshalIndent(build.Input.Properties, "", "  ")
	if err != nil {
		err = fmt.Errorf("failed to marshal build input properties: %w", err)
		return
	}
	// TODO(fxbug.dev/72956): Emit the build properties to a separate output log once
	// it's possible for recipe_bootstrap to emit build.proto to the same Logdog stream
	// as the recipe engine.
	logging.Infof(ctx, "resolved input properties: %s", string(b))
	return build, recipesDir, nil
}

func execute(ctx context.Context) error {
	outputPath := flag.String("output", "", "Path to write the final build.proto state to.")
	flag.Parse()

	build, recipesDir, err := setUpRecipes(ctx)
	// `recipesDir` might not exist depending on the setup failure mode, so ignore any
	// error when removing it.
	defer os.RemoveAll(recipesDir)
	if err != nil {
		if outputErr := outputBuildSummary(ctx, err.Error()); outputErr != nil {
			logging.Errorf(ctx, "Failed to output build summary after recipe setup failed: %v", outputErr)
		}
		return err
	}
	if err := executeRecipe(ctx, recipesDir, build, *outputPath); err != nil {
		return fmt.Errorf("failed to execute recipe: %w", err)
	}
	return nil
}

func main() {
	ctx := context.Background()
	ctx = gologger.StdConfig.Use(ctx)
	if err := execute(ctx); err != nil {
		logging.Errorf(ctx, err.Error())
		os.Exit(1)
	}
}
