// Copyright 2021 The Go 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 harnesses

import (
	"os/exec"
	"path/filepath"

	"golang.org/x/benchmarks/sweet/common"
	"golang.org/x/benchmarks/sweet/common/log"
)

type localBenchHarness struct {
	binName   string
	genArgs   func(cfg *common.Config, rcfg *common.RunConfig) []string
	beforeRun func(cfg *common.Config, rcfg *common.RunConfig) error
	noStdout  bool
}

func (h *localBenchHarness) CheckPrerequisites() error {
	return nil
}

func (h *localBenchHarness) Get(_ *common.GetConfig) error {
	return nil
}

func (h *localBenchHarness) Build(cfg *common.Config, bcfg *common.BuildConfig) error {
	return cfg.GoTool().BuildPath(bcfg.BenchDir, filepath.Join(bcfg.BinDir, h.binName))
}

func (h *localBenchHarness) Run(cfg *common.Config, rcfg *common.RunConfig) error {
	if h.beforeRun != nil {
		if err := h.beforeRun(cfg, rcfg); err != nil {
			return err
		}
	}
	cmd := exec.Command(
		filepath.Join(rcfg.BinDir, h.binName),
		append(rcfg.Args, h.genArgs(cfg, rcfg)...)...,
	)
	cmd.Env = cfg.ExecEnv.Collapse()
	if !h.noStdout {
		cmd.Stdout = rcfg.Results
	}
	cmd.Stderr = rcfg.Results
	log.TraceCommand(cmd, false)
	return cmd.Run()
}

func BiogoIgor() common.Harness {
	return &localBenchHarness{
		binName: "biogo-igor-bench",
		genArgs: func(cfg *common.Config, rcfg *common.RunConfig) []string {
			return []string{
				filepath.Join(rcfg.AssetsDir, "Homo_sapiens.GRCh38.dna.chromosome.22.gff"),
			}
		},
	}
}

func BiogoKrishna() common.Harness {
	return &localBenchHarness{
		binName: "biogo-krishna-bench",
		genArgs: func(cfg *common.Config, rcfg *common.RunConfig) []string {
			return []string{
				"-alignconc",
				"-tmp", rcfg.TmpDir,
				"-tmpconc",
				filepath.Join(rcfg.AssetsDir, "Mus_musculus.GRCm38.dna.nonchromosomal.fa"),
			}
		},
	}
}

func BleveIndex() common.Harness {
	return &localBenchHarness{
		binName: "bleve-index-bench",
		genArgs: func(cfg *common.Config, rcfg *common.RunConfig) []string {
			var args []string
			if rcfg.Short {
				args = []string{
					"-documents", "10",
					"-batch-size", "10",
				}
			} else {
				args = []string{
					"-documents", "1000",
					"-batch-size", "100",
				}
			}
			return append(args, filepath.Join(rcfg.AssetsDir, "enwiki-20080103-pages-articles.xml.bz2"))
		},
	}
}

func GopherLua() common.Harness {
	return &localBenchHarness{
		binName: "gopher-lua-bench",
		genArgs: func(cfg *common.Config, rcfg *common.RunConfig) []string {
			args := []string{
				filepath.Join(rcfg.AssetsDir, "k-nucleotide.lua"),
				filepath.Join(rcfg.AssetsDir, "input.txt"),
			}
			if rcfg.Short {
				args = append([]string{"-short"}, args...)
			}
			return args
		},
	}
}

func Markdown() common.Harness {
	return &localBenchHarness{
		binName: "markdown-bench",
		genArgs: func(cfg *common.Config, rcfg *common.RunConfig) []string {
			return []string{
				rcfg.AssetsDir,
			}
		},
	}
}
