// Copyright 2021 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 fint

import (
	"context"
	"errors"
	"fmt"
	"io"
	"path/filepath"
	"testing"

	"github.com/google/go-cmp/cmp"
	"go.fuchsia.dev/fuchsia/tools/lib/jsonutil"
)

// gnAnalyzeRunner conforms to the subprocessRunner interface but is
// specifically intended for testing functions that are only intended to use it
// to make a single `gn analyze` call.
type gnAnalyzeRunner struct {
	output gnAnalyzeOutput

	// Remaining fields are to be set by `Run()`.

	// The exact command that was run.
	cmd []string

	// The JSON input that was passed to the gn analyze command.
	input gnAnalyzeInput
}

func (r *gnAnalyzeRunner) Run(_ context.Context, cmd []string, _, _ io.Writer) error {
	if len(r.cmd) != 0 {
		return errors.New("Run() can only be called once per runner")
	}
	r.cmd = cmd

	// Relying on index is somewhat fragile but easier than the alternatives.
	inputPath := cmd[3]
	outputPath := cmd[4]

	if err := jsonutil.ReadFromFile(inputPath, &r.input); err != nil {
		return fmt.Errorf("failed to read GN analyze input: %w", err)
	}

	return jsonutil.WriteToFile(outputPath, r.output)
}

func (r *gnAnalyzeRunner) RunWithStdin(_ context.Context, _ []string, _, _ io.Writer, _ io.Reader) error {
	return nil
}

func TestShouldBuild(t *testing.T) {
	ctx := context.Background()

	testCases := []struct {
		name       string
		files      []string
		mockOutput gnAnalyzeOutput

		// Whether we expect `gn analyze` to be run in this test case.
		expectNoCommand bool

		// Whether this test case should determine that the build graph is
		// affected.
		expectShouldBuild bool

		// Whether this test case is expected to cause the function to return an
		// error.
		expectErr bool
	}{
		{
			name:              "unknown file type",
			files:             []string{"foo.invalid"},
			expectNoCommand:   true,
			expectShouldBuild: true,
		},
		{
			name: "affected",
			mockOutput: gnAnalyzeOutput{
				Status: buildGraphAffectedStatus,
			},
			expectShouldBuild: true,
		},
		{
			name: "unaffected",
			mockOutput: gnAnalyzeOutput{
				Status: buildGraphNotAffectedStatus,
			},
			expectShouldBuild: false,
		},
		{
			name: "unknown status",
			mockOutput: gnAnalyzeOutput{
				Status: unknownAffectedStatus,
			},
			expectShouldBuild: true,
		},
		{
			name: "invalid status",
			mockOutput: gnAnalyzeOutput{
				Status: "invalid",
			},
			expectErr: true,
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			if len(tc.files) == 0 {
				tc.files = []string{"foo/bar.cc", "baz.py"}
			}

			runner := &gnAnalyzeRunner{
				output: tc.mockOutput,
			}
			platform := "linux-x64"
			buildDir := filepath.Join(t.TempDir(), "build")
			checkoutDir := filepath.Join(t.TempDir(), "checkout")

			gotShouldBuild, err := shouldBuild(ctx, runner, buildDir, checkoutDir, platform, tc.files)
			if tc.expectErr && err == nil {
				t.Fatalf("Expected error but analysis succeeded")
			} else if !tc.expectErr && err != nil {
				t.Fatalf("Unexpected analysis error: %s", err)
			}

			if gotShouldBuild != tc.expectShouldBuild {
				t.Errorf("Wrong affected result: wanted %v, got %v", tc.expectShouldBuild, gotShouldBuild)
			}

			if tc.expectNoCommand {
				if len(runner.cmd) != 0 {
					t.Fatalf("Expected no command to be run, but this command was run: %v", runner.cmd)
				}
				// The remaining assertions deal only with the case where gn
				// analyze is expected to be run.
				return
			}

			expectedCmd := []string{thirdPartyPrebuilt(checkoutDir, platform, "gn"), "analyze", buildDir}
			if diff := cmp.Diff(runner.cmd[:len(expectedCmd)], expectedCmd); diff != "" {
				t.Fatalf("Wrong gn command run (-want +got):\n%s", diff)
			}

			if diff := cmp.Diff(formatFilePaths(tc.files), runner.input.Files); diff != "" {
				t.Fatalf("gn analyze received the wrong list of files (-want +got):\n%s", diff)
			}
		})
	}
}

func TestCanAnalyzeFiles(t *testing.T) {
	ctx := context.Background()

	testCases := []struct {
		name               string
		files              []string
		expectedCanAnalyze bool
	}{
		{
			name:               "no files",
			files:              []string{},
			expectedCanAnalyze: true,
		},
		{
			name:               "all file types supported",
			files:              []string{"foo.py", "baz.go", "abc/def.cc", "abc/OWNERS"},
			expectedCanAnalyze: true,
		},
		{
			name:               "some file types unsupported",
			files:              []string{"foo.py", "bar/baz.invalid"},
			expectedCanAnalyze: false,
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			canAnalyze := canAnalyzeFiles(ctx, tc.files)
			if canAnalyze != tc.expectedCanAnalyze {
				t.Errorf("Wrong canAnalyze result: wanted %v, got %v", tc.expectedCanAnalyze, canAnalyze)
			}
		})
	}
}
