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

// This file implements integration tests for the checkout package. It depends on a real
// gitiles project (fuchsia.googlesource.com/infra/testproject) with real Gerrit
// patchsets. These tests are skipped on CQ. since they are integration tests. You can run
// them locally by invoking `go test` without the -short flag.
package checkout

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"net/url"
	"os"
	"os/exec"
	"strings"
	"testing"

	buildbucketpb "go.chromium.org/luci/buildbucket/proto"
	"go.fuchsia.dev/infra/execution"
)

// Verifies that a repository is checked out via rebasing a patchset onto a commit when
// the build input contains a Gerrit change and Gitiles commit for the input repository.
// We always fail if there's a merge conflict when attempting to rebase, so this test only
// verifies the case where there is no conflict.
func TestCheckoutChange(t *testing.T) {
	os.Chdir(t.TempDir())

	ctx := context.Background()
	repo := url.URL{
		Scheme: "https",
		Host:   "fuchsia.googlesource.com",
		Path:   "infra/testproject",
	}
	input := &buildbucketpb.Build_Input{
		GitilesCommit: &buildbucketpb.GitilesCommit{
			Host:    "fuchsia.googlesource.com",
			Project: "infra/testproject",
			Id:      "813624618670bf1ae072a5e24d05b0bbda7240a0",
		},
		GerritChanges: []*buildbucketpb.GerritChange{{
			Host:     "fuchsia-review.googlesource.com",
			Project:  "infra/testproject",
			Change:   284673,
			Patchset: 3,
		}},
	}
	if err := doCheckout(ctx, input, repo); err != nil {
		t.Fatal(err)
	}

	var stdout, stderr bytes.Buffer
	executor := execution.NewExecutor(&stdout, &stderr, "")

	// Use the path to git loaded in the checkout package's init() function.
	if err := executor.Exec(ctx, git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil {
		t.Fatal(err, stderr.String())
	}
	t.Log(stdout.String())
	t.Log(stderr.String())

	actualLog := strings.TrimSpace(stdout.String())
	expectedLog := "28d5d51 Add rebased.txt\n8136246 Add README.md"
	if actualLog != expectedLog {
		t.Errorf("expected commit log:\n%s\ngot:\n%s", expectedLog, actualLog)
	}
}

// Verifies that a repository is checked out from a commit when the build input contains a
// Gitiles commit for the input repository.
func TestCheckoutCommit(t *testing.T) {
	os.Chdir(t.TempDir())

	ctx := context.Background()
	repo := url.URL{
		Scheme: "https",
		Host:   "fuchsia.googlesource.com",
		Path:   "infra/testproject",
	}
	input := &buildbucketpb.Build_Input{
		GitilesCommit: &buildbucketpb.GitilesCommit{
			Host:    "fuchsia.googlesource.com",
			Project: "infra/testproject",
			Id:      "813624618670bf1ae072a5e24d05b0bbda7240a0",
		},
	}
	if err := doCheckout(ctx, input, repo); err != nil {
		t.Fatal(err)
	}

	var stdout, stderr bytes.Buffer
	executor := execution.NewExecutor(&stdout, &stderr, "")

	// Use the path to git loaded in the checkout package's init() function.
	if err := executor.Exec(ctx, git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil {
		t.Fatal(err, stderr.String())
	}
	t.Log(stdout.String())
	t.Log(stderr.String())

	actualLog := strings.TrimSpace(stdout.String())
	expectedLog := "8136246 Add README.md"
	if actualLog != expectedLog {
		t.Errorf("expected commit log:\n%s\ngot:\n%s", expectedLog, actualLog)
	}
}

func TestCheckoutHead(t *testing.T) {
	os.Chdir(t.TempDir())

	ctx := context.Background()
	repo := url.URL{
		Scheme: "https",
		Host:   "fuchsia.googlesource.com",
		Path:   "infra/testproject",
	}
	input := &buildbucketpb.Build_Input{
		// Empty commit to force a checkout at HEAD.
		GitilesCommit: &buildbucketpb.GitilesCommit{},
	}
	if err := doCheckout(ctx, input, repo); err != nil {
		t.Fatal(err)
	}
}

func doCheckout(ctx context.Context, input *buildbucketpb.Build_Input, repoURL url.URL) error {
	// Verify the cwd is not a git checkout, but ends up being one after Checkout()
	// completes.
	inGitCheckout, err := isInGitCheckout(ctx)
	if err != nil {
		return err
	}
	if inGitCheckout {
		return errors.New("failed test precondition: already in a git checkout")
	}

	if err := Checkout(ctx, input, repoURL, "HEAD", ""); err != nil {
		return fmt.Errorf("checkout failed: %w", err)
	}

	inGitCheckout, err = isInGitCheckout(ctx)
	if err != nil {
		return err
	}
	if !inGitCheckout {
		return errors.New("expected to be in a git checkout after Checkout()")
	}
	return nil
}

func isInGitCheckout(ctx context.Context) (bool, error) {
	executor := execution.NewExecutor(os.Stderr, os.Stderr, "")
	if err := executor.Exec(ctx, git, "status"); err != nil {
		var errExit *exec.ExitError
		if errors.As(err, &errExit) && errExit.ExitCode() != 0 {
			return false, nil
		}
		return false, err
	}
	return true, nil
}
