// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package common

import (
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
	"encoding/json"
	"fmt"
	"os/exec"
	"path/filepath"
	"time"

	"dawn.googlesource.com/dawn/tools/src/fileutils"
)

type Builder struct {
	Name string // 'standalone', 'node'
	Out  string // Absolute path to the output directory
	CTS  string // Absolute path to the CTS root directory
	npx  string // Path to the npx executable
}

// BuildIfRequired calls Build() if the CTS sources have been modified since the last build.
func (b *Builder) BuildIfRequired(verbose bool, osWrapper oswrapper.OSWrapper) error {
	name := fmt.Sprintf("cts %v", b.Name)

	// Scan the CTS source to determine the most recent change to the CTS source
	mostRecentSourceChange, err := scanSourceTimestamps(filepath.Join(b.Out, "../src"), verbose)
	if err != nil {
		return fmt.Errorf("failed to scan source files for modified timestamps: %w", err)
	}

	type Cache struct {
		BuildTimestamp map[string]time.Time // name -> most recent timestamp
	}
	cache := Cache{BuildTimestamp: map[string]time.Time{}}

	cachePath := ""
	if home, err := osWrapper.UserHomeDir(); err == nil {
		cacheDir := filepath.Join(home, ".cache/webgpu")
		cachePath = filepath.Join(cacheDir, "run-cts.json")
		osWrapper.MkdirAll(cacheDir, 0777)
	}

	needsRebuild := true
	if cachePath != "" { // consult the cache to see if we need to rebuild
		if cacheFile, err := osWrapper.Open(cachePath); err == nil {
			if err := json.NewDecoder(cacheFile).Decode(&cache); err == nil {
				if fileutils.IsDir(b.Out, osWrapper) {
					needsRebuild = mostRecentSourceChange.After(cache.BuildTimestamp[b.Name])
				}
			}
			cacheFile.Close()
		}
	}

	if verbose {
		fmt.Println(name, "needs rebuild:", needsRebuild)
	}

	if needsRebuild {
		if err := b.Build(verbose, osWrapper); err != nil {
			return fmt.Errorf("failed to build %v: %w", name, err)
		}
	}

	if cachePath != "" {
		// Update the cache timestamp
		if cacheFile, err := osWrapper.Create(cachePath); err == nil {
			cache.BuildTimestamp[b.Name] = mostRecentSourceChange
			json.NewEncoder(cacheFile).Encode(&cache)
			cacheFile.Close()
		}
	}

	return nil
}

// Build executes the necessary build commands to build the CTS, including
// copying the cache files from gen to the out directory and compiling the
// TypeScript files down to JavaScript.
func (b *Builder) Build(verbose bool, fsReaderWrapper oswrapper.FilesystemReaderWriter) error {
	if verbose {
		start := time.Now()
		fmt.Printf("Building CTS %v...\n", b.Name)
		defer func() {
			fmt.Println("completed in", time.Since(start))
		}()
	}

	if err := fsReaderWrapper.MkdirAll(b.Out, 0777); err != nil {
		return err
	}

	if !fileutils.IsExe(b.npx, fsReaderWrapper) {
		return fmt.Errorf("cannot find npx at '%v'", b.npx)
	}

	for _, action := range []string{"run:generate-version", b.Name} {
		cmd := exec.Command(b.npx, "grunt", action)
		cmd.Dir = b.CTS
		out, err := cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("%w: %v", err, string(out))
		}
		if verbose {
			fmt.Println(string(out))
		}
	}

	return nil
}
