// Copyright 2017 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	cf "github.com/google/wuffs/cmd/commonflags"
)

func doBench(wuffsRoot string, args []string) error { return doBenchTest(wuffsRoot, args, true) }
func doTest(wuffsRoot string, args []string) error  { return doBenchTest(wuffsRoot, args, false) }

func doBenchTest(wuffsRoot string, args []string, bench bool) error {
	flags := flag.NewFlagSet("test", flag.ExitOnError)
	ccompilersFlag := flags.String("ccompilers", cf.CcompilersDefault, cf.CcompilersUsage)
	focusFlag := flags.String("focus", cf.FocusDefault, cf.FocusUsage)
	iterscaleFlag := flags.Int("iterscale", cf.IterscaleDefault, cf.IterscaleUsage)
	langsFlag := flags.String("langs", langsDefault, langsUsage)
	mimicFlag := flags.Bool("mimic", cf.MimicDefault, cf.MimicUsage)
	repsFlag := flags.Int("reps", cf.RepsDefault, cf.RepsUsage)
	skipgenFlag := flags.Bool("skipgen", skipgenDefault, skipgenUsage)
	skipgendepsFlag := flags.Bool("skipgendeps", skipgendepsDefault, skipgendepsUsage)

	if err := flags.Parse(args); err != nil {
		return err
	}

	langs, err := parseLangs(*langsFlag)
	if err != nil {
		return err
	}
	if !cf.IsAlphaNumericIsh(*ccompilersFlag) {
		return fmt.Errorf("bad -ccompilers flag value %q", *ccompilersFlag)
	}
	if !cf.IsAlphaNumericIsh(*focusFlag) {
		return fmt.Errorf("bad -focus flag value %q", *focusFlag)
	}
	if *iterscaleFlag < cf.IterscaleMin || cf.IterscaleMax < *iterscaleFlag {
		return fmt.Errorf("bad -iterscale flag value %d, outside the range [%d ..= %d]",
			*iterscaleFlag, cf.IterscaleMin, cf.IterscaleMax)
	}
	if *repsFlag < cf.RepsMin || cf.RepsMax < *repsFlag {
		return fmt.Errorf("bad -reps flag value %d, outside the range [%d ..= %d]",
			*repsFlag, cf.RepsMin, cf.RepsMax)
	}

	args = flags.Args()
	if len(args) == 0 {
		args = []string{"base", "std/..."}
	}

	cmdArgs := []string(nil)
	if bench {
		cmdArgs = append(cmdArgs, "bench",
			fmt.Sprintf("-iterscale=%d", *iterscaleFlag),
			fmt.Sprintf("-reps=%d", *repsFlag),
		)
	} else {
		cmdArgs = append(cmdArgs, "test")
	}
	if *focusFlag != "" {
		cmdArgs = append(cmdArgs, fmt.Sprintf("-focus=%s", *focusFlag))
	}
	if *mimicFlag {
		cmdArgs = append(cmdArgs, "-mimic")
	}

	h := testHelper{
		wuffsRoot:  wuffsRoot,
		langs:      langs,
		cmdArgs:    cmdArgs,
		ccompilers: *ccompilersFlag,
	}

	// Ensure that we are testing the latest version of the generated code.
	if !*skipgenFlag {
		gh := genHelper{
			wuffsRoot:   wuffsRoot,
			langs:       langs,
			skipgen:     *skipgenFlag,
			skipgendeps: *skipgendepsFlag,
		}
		for _, arg := range args {
			recursive := strings.HasSuffix(arg, "/...")
			if recursive {
				arg = arg[:len(arg)-4]
			}
			if arg == "" {
				continue
			}

			if err := gh.gen(arg, recursive); err != nil {
				return err
			}
		}
		if err := genrelease(wuffsRoot, langs, cf.Version{}); err != nil {
			return err
		}
	}

	failed := false
	for _, arg := range args {
		recursive := strings.HasSuffix(arg, "/...")
		if recursive {
			arg = arg[:len(arg)-4]
		}
		if arg == "" {
			continue
		}

		// Proceed with benching / testing the generated code.
		f, err := h.benchTest(arg, recursive)
		if err != nil {
			return err
		}
		failed = failed || f
	}
	if failed {
		s0, s1 := "test", "tests"
		if bench {
			s0, s1 = "bench", "benchmarks"
		}
		return fmt.Errorf("wuffs %s: some %s failed", s0, s1)
	}
	return nil
}

type testHelper struct {
	wuffsRoot  string
	langs      []string
	cmdArgs    []string
	ccompilers string
}

func (h *testHelper) benchTest(dirname string, recursive bool) (failed bool, err error) {
	if dirname == "base" {
		return false, nil
	}
	qualFilenames, dirnames, err := listDir(
		filepath.Join(h.wuffsRoot, filepath.FromSlash(dirname)), ".wuffs", recursive)
	if err != nil {
		return false, err
	}
	if len(qualFilenames) > 0 {
		f, err := h.benchTestDir(dirname)
		if err != nil {
			return false, err
		}
		failed = failed || f
	}
	if len(dirnames) > 0 {
		for _, d := range dirnames {
			f, err := h.benchTest(filepath.Join(dirname, d), recursive)
			if err != nil {
				return false, err
			}
			failed = failed || f
		}
	}
	return failed, nil
}

func (h *testHelper) benchTestDir(dirname string) (failed bool, err error) {
	if packageName := filepath.Base(dirname); !validName(packageName) {
		return false, fmt.Errorf(`invalid package %q, not in [a-z0-9]+`, packageName)
	}

	for _, lang := range h.langs {
		command := "wuffs-" + lang
		args := []string(nil)
		args = append(args, h.cmdArgs...)
		if lang == "c" {
			args = append(args, fmt.Sprintf("-ccompilers=%s", h.ccompilers))
		}
		args = append(args, filepath.Join(h.wuffsRoot, "test", lang, filepath.FromSlash(dirname)))
		cmd := exec.Command(command, args...)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if err := cmd.Run(); err == nil {
			// No-op.
		} else if _, ok := err.(*exec.ExitError); ok {
			failed = true
		} else {
			return false, err
		}
	}
	return failed, nil
}
