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

import (
	"fmt"
	"reflect"
	"strings"
	"testing"

	"fuchsia.googlesource.com/infra/infra/fxicfg/errs"
	protos "fuchsia.googlesource.com/infra/infra/fxicfg/starlark/protos/recipes"
	"github.com/golang/protobuf/proto"
	luci "go.chromium.org/luci/starlark/interpreter"
	"go.chromium.org/luci/starlark/starlarkproto"
)

// Default name of the starlark file to execute first.
const entrypoint = "main.star"

// This is a minimal test to verify that the Generator keeps working.
func TestSmokeTestGenerate(t *testing.T) {
	srcs := make(map[string]string)
	srcs[entrypoint] = `
load("//configs/example.star", example="example")
output = example`

	srcs["configs/example.star"] = `
load("@proto//recipes/example.proto", example_pb="recipes.example")

# See fxicfg/starlark/protos/recipes/example.proto
example = example_pb.Example(
	field_a = example_pb.Example.FieldA(
	value = 3,
	))`

	_, globals, err := Generate(luci.MemoryLoader(srcs), entrypoint)
	if err != nil {
		t.Fatal(err)
	}
	message := globals["output"].(*starlarkproto.Message)
	pb, err := message.ToProto()
	if err != nil {
		t.Fatal(err)
	}

	actual := pb.(*protos.Example)
	expected := &protos.Example{
		FieldA: &protos.Example_FieldA{
			Value: 3,
		},
	}

	if !proto.Equal(actual, expected) {
		t.Errorf("wanted:\n%v\ngot:\n%v", expected, actual)
	}
}

// TODO(kjharland): Refactor so that this test's dependency on Generate() is acyclic and
// this test case can live in the builtins/ package.
func TestBuiltinSetOutputDir(t *testing.T) {
	tests := []struct {
		name              string
		sources           map[string]string
		expectErr         bool
		expectedOutputDir string
	}{
		{
			name: "should err if set_output_dir is called twice",
			sources: map[string]string{
				entrypoint: `
fxicfg.set_output_dir("output_a")
fxicfg.set_output_dir("output_b")
`,
			},
			expectErr: true,
		},
		{
			name: "should set the output directory",
			sources: map[string]string{entrypoint: `
fxicfg.set_output_dir("output_a")
`,
			},
			expectedOutputDir: "output_a",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			state, _, err := Generate(luci.MemoryLoader(tt.sources), entrypoint)
			switch {
			case err != nil && !tt.expectErr:
				t.Errorf("unexpected error: %v", err)
				return
			case err == nil && tt.expectErr:
				t.Error("wanted an error but got nil")
				return
			case err != nil && tt.expectErr:
				return
			}

			expected := tt.expectedOutputDir
			actual := state.OutputDir
			if expected != actual {
				t.Errorf("wanted output dir %q but got %q", expected, actual)
			}
		})
	}
}

// TODO(kjharland): Refactor so that this test's dependency on Generate() is acyclic and
// this test case can live in the builtins/ package.
func TestBuiltinAddOutputFile(t *testing.T) {

	// A dummy starlark module that constructs an Example proto message for testing.
	textprotoMod := `
load("@proto//recipes/example.proto", example_pb="recipes.example")

# See fxicfg/starlark/protos/recipes/example.proto

_one = example_pb.Example(
  field_a = example_pb.Example.FieldA(
    value = 1,
	),
)

_two = example_pb.Example(
	field_a = example_pb.Example.FieldA(
		value = 2,
	),
)

textprotos = struct(
	one = proto.to_textpb(_one),
	two = proto.to_textpb(_two),
)
`

	tests := []struct {
		name    string
		sources map[string]string
		// Expect a specific error reason because a boolean is not enough; Starlark
		// interpretation may fail for various reasons, and (true|false) tests are unreliable.
		expectedErrReason errs.Reason
		expectedOutputs   map[string]proto.Message
	}{
		{
			name: "should err if duplicate paths are added",
			sources: map[string]string{
				"textprotos.star": textprotoMod,
				entrypoint: `
load("//textprotos.star", textprotos="textprotos")

fxicfg.add_output_file(path="example/either.txt", data=textprotos.one)
fxicfg.add_output_file(path="example/either.txt", data=textprotos.two)
`,
			},
			expectedErrReason: errs.ErrInvalidArg,
		},
		{
			name: "should err if an absolute path is given",
			sources: map[string]string{
				"textprotos.star": textprotoMod,
				entrypoint: `
load("//textprotos.star", textprotos="textprotos")

fxicfg.add_output_file(path="/one.txt", data=textprotos.one)
`,
			},
			expectedErrReason: errs.ErrInvalidArg,
		},
		{
			name: "should add a file",
			sources: map[string]string{
				"textprotos.star": textprotoMod,
				entrypoint: `
load("//textprotos.star", textprotos="textprotos")

fxicfg.add_output_file(path="example/two.txt", data=textprotos.two)
`,
			},
			expectedOutputs: map[string]proto.Message{
				"example/two.txt": &protos.Example{
					FieldA: &protos.Example_FieldA{
						Value: 2,
					},
				},
			},
		},
		{
			name: "should add multiple files",
			sources: map[string]string{
				"textprotos.star": textprotoMod,
				entrypoint: `
load("//textprotos.star", textprotos="textprotos")

fxicfg.add_output_file(path="example/one.txt", data=textprotos.one)
fxicfg.add_output_file(path="example/two.txt", data=textprotos.two)
`,
			},
			expectedOutputs: map[string]proto.Message{
				"example/one.txt": &protos.Example{
					FieldA: &protos.Example_FieldA{
						Value: 1,
					},
				},

				"example/two.txt": &protos.Example{
					FieldA: &protos.Example_FieldA{
						Value: 2,
					},
				},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			state, _, err := Generate(luci.MemoryLoader(tt.sources), entrypoint)
			if err := checkErrorReason(tt.expectedErrReason, err); err != nil {
				t.Error(err)
				return
			}
			if tt.expectedErrReason != "" {
				return // Already checked the error.
			}

			expected := make(map[string][]byte)
			for k, v := range tt.expectedOutputs {
				textproto := proto.MarshalTextString(v)
				expected[k] = []byte(textproto)
			}

			actual := state.OutputFiles
			if !reflect.DeepEqual(expected, actual) {
				t.Errorf("wanted\n%v\nbut got\n%v", expected, actual)
			}
		})
	}
}

// Helper function to ensure an error emitted by the interpreter is correct. Returns an
// error if `actual` is a starlark syntax or semantic error. Returns nil If `actual`
// originates from within this interpreter and its message matches `reason`.
func checkErrorReason(reason errs.Reason, actual error) error {
	switch {
	case reason == "" && actual != nil:
		return fmt.Errorf("unexpected error: %q", actual.Error())
	case actual == nil && reason != "":
		return fmt.Errorf("wanted error with reason %q but got nil", reason)
	case actual == nil && reason == "":
		return nil // all ok
	}
	if strings.HasPrefix(actual.Error(), string(reason)) {
		return nil
	}
	return fmt.Errorf("wanted error reason %q but got %q", reason, actual.Error())
}
