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

import (
	"encoding/json"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"testing"
)

// Created by `fuzz_package` in //build/fuzzing/fuzzer.gni
type FuzzSpec struct {
	Host    bool     `json:"fuzz_host"`
	Package string   `json:"fuzz_package"`
	Targets []string `json:"fuzz_targets"`
}

func TestFxFuzzLib(t *testing.T) {
	fuchsiaDir, found := os.LookupEnv("FUCHSIA_DIR")
	if !found {
		t.SkipNow()
	}
	scriptsFuzzingTests := []string{
		"cipd_test.py",
		"device_test.py",
		"fuzzer_test.py",
		"host_test.py",
	}
	for _, test := range scriptsFuzzingTests {
		pytest := path.Join(fuchsiaDir, "scripts", "fuzzing", "test", test)
		cmd := exec.Command("python", pytest)
		output, err := cmd.CombinedOutput()
		if err != nil {
			t.Errorf("%s failed:: %v", test, err)
		}
		t.Log(string(output[:]))
	}
}

func TestHostFuzzers(t *testing.T) {
	// Search the build directory structure for host variant fuzzer builds.
	// This is necessarily sensitive to the layout of the build directory and
	// will need to be updated if the host tests are moved or the host fuzzer
	// builds' names change.
	testBin, err := os.Executable()
	if err != nil {
		t.Fatalf("Failed to determine executable path: %v", err)
	}
	fxBuildDir := path.Dir(path.Dir(testBin))

	// Find the fuzzers that should have been built for host.
	jsonPath := path.Join(fxBuildDir, "fuzzers.json")
	_, err = os.Stat(jsonPath)
	if err != nil && os.IsNotExist(err) {
		t.SkipNow()
	}
	jsonFile, err := os.Open(jsonPath)
	if err != nil {
		t.Fatalf("Failed to find fuzzer.json: %v", err)
	}
	defer jsonFile.Close()

	jsonData, err := ioutil.ReadAll(jsonFile)
	if err != nil {
		t.Fatalf("Failed to read fuzzer.json: %v", err)
	}

	var specs []FuzzSpec
	err = json.Unmarshal(jsonData, &specs)
	if err != nil {
		t.Fatalf("Failed to parse fuzzer.json: %v", err)
	}
	fuzzers := []string{}
	for _, spec := range specs {
		if spec.Host {
			fuzzers = append(fuzzers, spec.Targets...)
		}
	}

	// Create a empty file to act as a single input to each fuzzer.
	variants, err := filepath.Glob(path.Join(fxBuildDir, "host_*-fuzzer"))
	if err != nil {
		t.Fatalf("Failed to glob host fuzzer build directories: %v", err)
	}
	if len(variants) == 0 {
		t.SkipNow()
	}
	tempFile, err := ioutil.TempFile("", "empty.input")
	if err != nil {
		t.Fatalf("Failed to create empty input: %v", err)
	}
	tempName := tempFile.Name()
	tempFile.Close()
	defer os.Remove(tempName)

	// Check that each fuzzer runs and exits cleanly.
	for _, variant := range variants {
		for _, fuzzer := range fuzzers {
			cmd := exec.Command(path.Join(variant, fuzzer), tempName)
			output, err := cmd.CombinedOutput()
			if err != nil {
				t.Errorf("Failed to run %s: %v", fuzzer, err)
			}
			t.Log(string(output[:]))
		}
	}
}
