// Copyright 2018 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 testexec

import (
	"bufio"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"fuchsia.googlesource.com/infra/infra/fuchsia"
)

const (
	// TestSpecSuffix is the file suffix identifying a test spec.
	TestSpecSuffix = ".spec.json"

	// HostDepsSuffix is the file suffix identifying a file giving the host-side runtime
	// depedencies of a test.
	HostDepsSuffix = ".spec.data"
)

// TestSpec is the specification for a single test and the environments it
// should be executed in.
type TestSpec struct {
	// Test is the test that this specification is for.
	Test `json:"test"`

	// Envs is a set of environments that the test should be executed in.
	Envs []Environment `json:"environments"`

	// HostDeps are the host-side runtime depedencies of the test.
	HostDeps []string
}

// Test encapsulates details about a particular test.
type Test struct {
	// Name is the full, GN source-relative target name of the test
	// (e.g., //garnet/bin/foo/tests:foo_tests).
	Name string `json:"name"`

	// Location is a unique reference to a test: for example, a filesystem
	// path or a Fuchsia URI.
	Location string `json:"location"`
}

func (spec TestSpec) validateAgainst(platforms []DimensionSet) error {
	if spec.Test.Name == "" {
		return fmt.Errorf("A test spec's test must have a non-empty name")
	}
	if spec.Test.Location == "" {
		return fmt.Errorf("A test spec's test must have a non-empty location")
	}

	resolvesToOneOf := func(env Environment, platforms []DimensionSet) bool {
		for _, platform := range platforms {
			if env.Dimensions.resolvesTo(platform) {
				return true
			}
		}
		return false
	}

	var badEnvs []Environment
	for _, env := range spec.Envs {
		if !resolvesToOneOf(env, platforms) {
			badEnvs = append(badEnvs, env)
		}
	}
	if len(badEnvs) > 0 {
		return fmt.Errorf(
			`the following environments of test\n%+v were malformed
			or did not match any available test platforms:\n%+v`,
			spec.Test, badEnvs)
	}
	return nil
}

// ValidateTestSpecs validates a list of test specs against a list of test
// platform dimension sets.
func ValidateTestSpecs(specs []TestSpec, platforms []DimensionSet) error {
	errMsg := ""
	for _, spec := range specs {
		if err := spec.validateAgainst(platforms); err != nil {
			errMsg += fmt.Sprintf("\n%v", err)
		}
	}
	if errMsg != "" {
		return fmt.Errorf(errMsg)
	}
	return nil
}

// PkgTestSpecDir returns the directory where associated test specs may be written,
// given a package target.
func PkgTestSpecDir(fuchsiaBuildDir string, pkg fuchsia.Target) string {
	return filepath.Join(fuchsiaBuildDir, pkg.BuildDir, pkg.Name)
}

// HostTestSpecDir returns the directory where associated test specs may be written,
// given a host test target.
func HostTestSpecDir(fuchsiaBuildDir string, hostTest fuchsia.Target) string {
	return filepath.Join(fuchsiaBuildDir, hostTest.BuildDir)
}

func readLinesFromFile(path string) ([]string, error) {
	fd, err := os.Open(path)
	defer fd.Close()
	if err != nil {
		return nil, fmt.Errorf("failed to open %s: %v", path, err)
	}

	reader := bufio.NewReader(fd)
	lines := []string{}
	for {
		line, err := reader.ReadString('\n')
		if err == io.EOF {
			break
		} else if err != nil {
			return nil, fmt.Errorf("failed to read line from %s: %v", path, err)
		}
		line = strings.TrimRight(line, "\n")
		lines = append(lines, line)
	}
	return lines, nil
}

// LoadTestSpecs loads a set of test specifications from a list of Fuchsia
// package targets and a list of host test targets.
func LoadTestSpecs(fuchsiaBuildDir string, pkgs, hostTests []fuchsia.Target) ([]TestSpec, error) {
	// First, load the test specs associated to the given packages.
	//
	// It is guaranteed that a test spec will be written to the build directory of the
	// corresponding package its test was defined in: specifically, it will be put in
	// <target_out_dir of the test package>/<test package name>.
	specs := []TestSpec{}

	decodeTestSpecs := func(targets []fuchsia.Target, testSpecDir func(string, fuchsia.Target) string) error {
		for _, target := range targets {
			specDir := testSpecDir(fuchsiaBuildDir, target)
			// If the associated test spec directory does not exist, the package specified no
			// tests.
			if _, err := os.Stat(specDir); os.IsNotExist(err) {
				continue
			}

			// Non-recursively enumerate the files in this directory; it's guaranteed that
			// the test specs will be found here if generated.
			entries, err := ioutil.ReadDir(specDir)
			if err != nil {
				return err
			}

			for _, entry := range entries {
				if entry.IsDir() {
					continue
				}

				// Open, read, and parse any test spec found. Look for any associated host-side
				// runtime depedencies.
				path := filepath.Join(specDir, entry.Name())
				if strings.HasSuffix(path, TestSpecSuffix) {
					specFile, err := os.Open(path)
					defer specFile.Close()
					if err != nil {
						return fmt.Errorf("failed to open %s: %v", path, err)
					}

					var spec TestSpec
					if err := json.NewDecoder(specFile).Decode(&spec); err != nil {
						return fmt.Errorf("failed to decode %s: %v", path, err)
					}

					// If there is not an associated host deps file, there are no host deps, which
					// is okay and not a failure mode.
					hostDepsPath := strings.Replace(path, TestSpecSuffix, HostDepsSuffix, 1)
					_, err = os.Stat(hostDepsPath)
					if err == nil {
						deps, err := readLinesFromFile(hostDepsPath)
						if err != nil {
							return err
						}
						spec.HostDeps = deps
					} else if !os.IsNotExist(err) {
						return err
					}
					specs = append(specs, spec)
				}
			}
		}
		return nil
	}

	if err := decodeTestSpecs(pkgs, PkgTestSpecDir); err != nil {
		return nil, err
	}
	if err := decodeTestSpecs(hostTests, HostTestSpecDir); err != nil {
		return nil, err
	}

	return specs, nil
}
