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

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"testing"
	"time"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

// EndToEndTest simplifies the creation of end-to-end tests which compile a FIDL
// library, and produce JSON IR, read back in Go using fidlgen.
//
// Example usage:
//
//	root := EndToEndTest{T: t}.Single(`library example; struct MyStruct {};`)
//
// If dependencies are needed:
//
//	root := EndToEndTest{T: t}
//	    .WithDependency(`library dep; struct S{};`)
//	    .Single(`library example; struct MyStruct{ dep.S foo};`)
type EndToEndTest struct {
	*testing.T
	wd         string
	deps       []string
	experiment []string
	available  []string
}

var fidlc = flag.String("fidlc", "", "Path to fidlc.")

// WithDependency adds the source text for a dependency.
func (t EndToEndTest) WithDependency(content string) EndToEndTest {
	t.deps = append(t.deps, content)
	return t
}

// WithAvailable adds an --available flag to select a version for a platform.
func (t EndToEndTest) WithAvailable(platform string, version string) EndToEndTest {
	t.available = append(t.available, platform+":"+version)
	return t
}

// WithExperiment adds the input as an experimental flag.
func (t EndToEndTest) WithExperiment(f string) EndToEndTest {
	t.experiment = append(t.experiment, f)
	return t
}

// WithWorkingDirectory sets the working directory of any associated fidlc
// invocation. If unset, the process's current working directory will be used.
func (t EndToEndTest) WithWorkingDirectory(wd string) EndToEndTest {
	t.wd = wd
	return t
}

// Single compiles a single FIDL file, and returns a Root.
func (t EndToEndTest) Single(content string) fidlgen.Root {
	return t.Multiple([]string{content})
}

// Multiple compiles multiple FIDL files, and returns a Root.
//
// The mapping of `contents` to the list of generated FIDL source files
// preserves ordering (by index to lexicographically on filename).
func (t EndToEndTest) Multiple(contents []string) fidlgen.Root {
	if len(contents) == 0 {
		t.Fatal("no FIDL file contents provided")
	}

	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
	defer cancel()

	var (
		base        = t.TempDir()
		dotJSONFile = filepath.Join(base, "main.fidl.json")
		params      = []string{
			"--json", dotJSONFile,
		}
	)

	// And one file for each dependency.
	for i, dep := range t.deps {
		f, err := os.CreateTemp(base, fmt.Sprintf("dep_%d.fidl", i))
		if err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(f.Name(), []byte(dep), 0o600); err != nil {
			f.Close()
			t.Fatal(err)
		}
		if err := f.Close(); err != nil {
			t.Fatal(err)
		}
		params = append(params, "--files", f.Name())
	}

	for _, a := range t.available {
		params = append(params, "--available", a)
	}

	for _, e := range t.experiment {
		params = append(params, "--experimental", e)
	}

	// And one file for each of the given contents.
	params = append(params, "--files")
	for i, content := range contents {
		f, err := os.CreateTemp(base, fmt.Sprintf("lib_%d.fidl", i))
		if err != nil {
			t.Fatal(err)
		}
		if err := os.WriteFile(f.Name(), []byte(content), 0o600); err != nil {
			f.Close()
			t.Fatal(err)
		}
		if err := f.Close(); err != nil {
			t.Fatal(err)
		}
		params = append(params, f.Name())
	}

	fidlcPath := *fidlc
	if t.wd != "" {
		// Absolutize for access in the case of an arbitrary working directory.
		var err error
		fidlcPath, err = filepath.Abs(fidlcPath)
		if err != nil {
			log.Fatalf("could not derive absolute `fidlc` path: %s", err)
		}
	}

	var (
		cmd         = exec.CommandContext(ctx, fidlcPath, params...)
		fidlcStdout = new(bytes.Buffer)
		fidlcStderr = new(bytes.Buffer)
	)
	cmd.Stdout = fidlcStdout
	cmd.Stderr = fidlcStderr
	cmd.Dir = t.wd // Uses current working directory if empty.

	if err := cmd.Run(); err != nil {
		t.Logf("fidlc cmdline: %v %v", fidlcPath, params)
		t.Logf("fidlc stdout: %s", fidlcStdout.String())
		t.Logf("fidlc stderr: %s", fidlcStderr.String())
		if t.wd != "" {
			t.Logf("fidlc working directory: %s", t.wd)
		}
		t.Fatal(err)
	}

	root, err := fidlgen.ReadJSONIr(dotJSONFile)
	if err != nil {
		t.Fatal(err)
	}

	return root
}
