package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"strings"
	"testing"

	expect "github.com/Netflix/go-expect"
	tfe "github.com/hashicorp/go-tfe"
	"github.com/hashicorp/terraform/internal/e2e"
	tfversion "github.com/hashicorp/terraform/version"
)

var terraformBin string
var cliConfigFileEnv string

var tfeClient *tfe.Client
var tfeHostname string
var tfeToken string
var verboseMode bool

func TestMain(m *testing.M) {
	teardown := setup()
	code := m.Run()
	teardown()

	os.Exit(code)
}

func accTest() bool {
	// TF_ACC is set when we want to run acceptance tests, meaning it relies on
	// network access.
	return os.Getenv("TF_ACC") != ""
}

func hasHostname() bool {
	return os.Getenv("TFE_HOSTNAME") != ""
}

func hasToken() bool {
	return os.Getenv("TFE_TOKEN") != ""
}

func hasRequiredEnvVars() bool {
	return accTest() && hasHostname() && hasToken()
}

func skipIfMissingEnvVar(t *testing.T) {
	if !hasRequiredEnvVars() {
		t.Skip("Skipping test, required environment variables missing. Use `TF_ACC`, `TFE_HOSTNAME`, `TFE_TOKEN`")
	}
}

func setup() func() {
	tfOutput := flag.Bool("tfoutput", false, "This flag produces the terraform output from tests.")
	flag.Parse()
	verboseMode = *tfOutput

	setTfeClient()
	teardown := setupBinary()

	return func() {
		teardown()
	}
}
func testRunner(t *testing.T, cases testCases, orgCount int, tfEnvFlags ...string) {
	for name, tc := range cases {
		tc := tc // rebind tc into this lexical scope
		t.Run(name, func(subtest *testing.T) {
			subtest.Parallel()

			orgNames := []string{}
			for i := 0; i < orgCount; i++ {
				organization, cleanup := createOrganization(t)
				t.Cleanup(cleanup)
				orgNames = append(orgNames, organization.Name)
			}

			exp, err := expect.NewConsole(defaultOpts()...)
			if err != nil {
				subtest.Fatal(err)
			}
			defer exp.Close()

			tmpDir := t.TempDir()

			tf := e2e.NewBinary(t, terraformBin, tmpDir)
			tfEnvFlags = append(tfEnvFlags, "TF_LOG=INFO")
			tfEnvFlags = append(tfEnvFlags, cliConfigFileEnv)
			for _, env := range tfEnvFlags {
				tf.AddEnv(env)
			}

			var orgName string
			for index, op := range tc.operations {
				switch orgCount {
				case 0:
					orgName = ""
				case 1:
					orgName = orgNames[0]
				default:
					orgName = orgNames[index]
				}

				op.prep(t, orgName, tf.WorkDir())
				for _, tfCmd := range op.commands {
					cmd := tf.Cmd(tfCmd.command...)
					cmd.Stdin = exp.Tty()
					cmd.Stdout = exp.Tty()
					cmd.Stderr = exp.Tty()

					err = cmd.Start()
					if err != nil {
						subtest.Fatal(err)
					}

					if tfCmd.expectedCmdOutput != "" {
						got, err := exp.ExpectString(tfCmd.expectedCmdOutput)
						if err != nil {
							subtest.Fatalf("error while waiting for output\nwant: %s\nerror: %s\noutput\n%s", tfCmd.expectedCmdOutput, err, got)
						}
					}

					lenInput := len(tfCmd.userInput)
					lenInputOutput := len(tfCmd.postInputOutput)
					if lenInput > 0 {
						for i := 0; i < lenInput; i++ {
							input := tfCmd.userInput[i]
							exp.SendLine(input)
							// use the index to find the corresponding
							// output that matches the input.
							if lenInputOutput-1 >= i {
								output := tfCmd.postInputOutput[i]
								_, err := exp.ExpectString(output)
								if err != nil {
									subtest.Fatal(err)
								}
							}
						}
					}

					err = cmd.Wait()
					if err != nil && !tfCmd.expectError {
						subtest.Fatal(err)
					}
				}
			}

			if tc.validations != nil {
				tc.validations(t, orgName)
			}
		})
	}
}

func setTfeClient() {
	tfeHostname = os.Getenv("TFE_HOSTNAME")
	tfeToken = os.Getenv("TFE_TOKEN")

	cfg := &tfe.Config{
		Address: fmt.Sprintf("https://%s", tfeHostname),
		Token:   tfeToken,
	}

	if tfeHostname != "" && tfeToken != "" {
		// Create a new TFE client.
		client, err := tfe.NewClient(cfg)
		if err != nil {
			fmt.Printf("Could not create new tfe client: %v\n", err)
			os.Exit(1)
		}
		tfeClient = client
	}
}

func setupBinary() func() {
	log.Println("Setting up terraform binary")
	tmpTerraformBinaryDir, err := ioutil.TempDir("", "terraform-test")
	if err != nil {
		fmt.Printf("Could not create temp directory: %v\n", err)
		os.Exit(1)
	}
	log.Println(tmpTerraformBinaryDir)
	currentDir, err := os.Getwd()
	defer os.Chdir(currentDir)
	if err != nil {
		fmt.Printf("Could not change directories: %v\n", err)
		os.Exit(1)
	}
	// Getting top level dir
	dirPaths := strings.Split(currentDir, "/")
	log.Println(currentDir)
	topLevel := len(dirPaths) - 3
	topDir := strings.Join(dirPaths[0:topLevel], "/")

	if err := os.Chdir(topDir); err != nil {
		fmt.Printf("Could not change directories: %v\n", err)
		os.Exit(1)
	}

	cmd := exec.Command(
		"go",
		"build",
		"-o", tmpTerraformBinaryDir,
		"-ldflags", fmt.Sprintf("-X \"github.com/hashicorp/terraform/version.Prerelease=%s\"", tfversion.Prerelease),
	)
	err = cmd.Run()
	if err != nil {
		fmt.Printf("Could not run exec command: %v\n", err)
		os.Exit(1)
	}

	credFile := fmt.Sprintf("%s/dev.tfrc", tmpTerraformBinaryDir)
	writeCredRC(credFile)

	terraformBin = fmt.Sprintf("%s/terraform", tmpTerraformBinaryDir)
	cliConfigFileEnv = fmt.Sprintf("TF_CLI_CONFIG_FILE=%s", credFile)

	return func() {
		os.RemoveAll(tmpTerraformBinaryDir)
	}
}

func writeCredRC(file string) {
	creds := credentialBlock()
	f, err := os.Create(file)
	if err != nil {
		fmt.Printf("Could not create file: %v\n", err)
		os.Exit(1)
	}
	_, err = f.WriteString(creds)
	if err != nil {
		fmt.Printf("Could not write credentials: %v\n", err)
		os.Exit(1)
	}
	f.Close()
}

func credentialBlock() string {
	return fmt.Sprintf(`
credentials "%s" {
  token = "%s"
}`, tfeHostname, tfeToken)
}
