//go:build ignore
// +build ignore

package main

import (
	"flag"
	"log"
	"os"
	"path"
	"path/filepath"
	"runtime"

	"github.com/mmcloughlin/avo/internal/prnt"
	"github.com/mmcloughlin/avo/tests/thirdparty"
)

var (
	suitefilename = flag.String("suite", "", "third-party test suite configuration")
	output        = flag.String("output", "", "path to output file (default stdout)")
)

func main() {
	if err := mainerr(); err != nil {
		log.Fatal(err)
	}
}

func mainerr() error {
	flag.Parse()

	// Read third-party test suite.
	suite, err := thirdparty.LoadSuiteFile(*suitefilename)
	if err != nil {
		return err
	}

	if err := suite.Validate(); err != nil {
		return err
	}

	// Determine output.
	w := os.Stdout
	if *output != "" {
		f, err := os.Create(*output)
		if err != nil {
			return err
		}
		defer f.Close()
		w = f
	}

	// Generate workflow file.
	b, err := GenerateWorkflow(suite)
	if err != nil {
		return err
	}

	// Write output.
	if _, err := w.Write(b); err != nil {
		return err
	}

	return nil
}

func GenerateWorkflow(s *thirdparty.Suite) ([]byte, error) {
	g := &prnt.Generator{}
	g.SetIndentString("  ")

	_, self, _, _ := runtime.Caller(0)
	g.Linef("# Code generated by %s. DO NOT EDIT.", filepath.Base(self))
	g.NL()

	// Header.
	g.Linef("name: packages")

	g.Linef("permissions:")
	g.Linef("  contents: read")

	g.Linef("on:")
	g.Linef("  push:")
	g.Linef("    branches:")
	g.Linef("      - master")
	g.Linef("  pull_request:")

	// One job per test case.
	g.Linef("jobs:")
	g.Indent()
	for _, t := range s.Projects.Tests() {
		g.Linef("%s:", t.ID())
		g.Indent()

		g.Linef("runs-on: ubuntu-latest")
		if t.Project.Skip() {
			g.Linef("if: false # skip: %s", t.Project.Reason())
		}
		g.Linef("steps:")
		g.Indent()

		// Install Go.
		g.Linef("- name: Install Go")
		g.Linef("  uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f # v3.3.1")
		g.Linef("  with:")
		g.Linef("    go-version: 1.19.x")
		g.Linef("    check-latest: true")

		// Checkout avo.
		avodir := "avo"
		g.Linef("- name: Checkout avo")
		g.Linef("  uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0")
		g.Linef("  with:")
		g.Linef("    path: %s", avodir)
		g.Linef("    persist-credentials: false")

		// Checkout the third-party package.
		pkgdir := t.Project.Repository.Name
		g.Linef("- name: Checkout %s", t.Project.Repository)
		g.Linef("  uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0")
		g.Linef("  with:")
		g.Linef("    repository: %s", t.Project.Repository)
		g.Linef("    ref: %s", t.Project.Version)
		g.Linef("    path: %s", pkgdir)
		g.Linef("    persist-credentials: false")

		// Build steps.
		c := &thirdparty.Context{
			AvoDirectory:        path.Join("${{ github.workspace }}", avodir),
			RepositoryDirectory: path.Join("${{ github.workspace }}", pkgdir),
		}

		for _, step := range t.Package.Steps(c) {
			g.Linef("- name: %s", step.Name)
			g.Linef("  working-directory: %s", path.Join(pkgdir, step.WorkingDirectory))
			if len(step.Commands) == 1 {
				g.Linef("  run: %s", step.Commands[0])
			} else {
				g.Linef("  run: |")
				for _, cmd := range step.Commands {
					g.Linef("    %s", cmd)
				}
			}
		}

		g.Dedent()
		g.Dedent()
	}
	g.Dedent()

	return g.Result()
}
