// Copyright 2021 The Tint 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
//
//     http://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.

// trim-includes is a tool to try removing unnecessary include statements from
// all .cc and .h files in the tint project.
//
// trim-includes removes each #include from each file, then runs the provided
// build script to determine whether the line was necessary. If the include is
// required, it is restored, otherwise it is left deleted.
// After all the #include statements have been tested, the file is
// clang-formatted and git staged.
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"time"

	"dawn.googlesource.com/tint/tools/src/trim-includes/glob"
)

var (
	// Directory to this .go file
	toolRoot = getToolRoot()
	// Root directory of the Tint project
	projectRoot = getProjectRoot(toolRoot)

	// Path to the build script to run after each attempting to remove each
	// #include
	buildScript = ""
)

func main() {
	if err := run(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

func showUsage() {
	fmt.Println(`
trim-includes is a tool to try removing unnecessary include statements from all
.cc and .h files in the tint project.

trim-includes removes each #include from each file, then runs the provided build
script to determine whether the line was necessary. If the include is required,
it is restored, otherwise it is left deleted.
After all the #include statements have been tested, the file is clang-formatted
and git staged.

Usage:
  trim-includes <path-to-build-script>`)
	os.Exit(1)
}

func run() error {
	flag.Parse()
	args := flag.Args()
	if len(args) < 1 {
		showUsage()
	}

	var err error
	buildScript, err = exec.LookPath(args[0])
	if err != nil {
		return err
	}
	buildScript, err = filepath.Abs(buildScript)
	if err != nil {
		return err
	}

	cfg, err := glob.LoadConfig("config.cfg")
	if err != nil {
		return err
	}

	fmt.Println("Checking the project builds with no changes...")
	ok, err := tryBuild()
	if err != nil {
		return err
	}
	if !ok {
		return fmt.Errorf("Project does not build without edits")
	}

	fmt.Println("Scanning for files...")
	paths, err := glob.Scan(projectRoot, cfg)
	if err != nil {
		return err
	}

	fmt.Printf("Loading %v source files...\n", len(paths))
	files, err := loadFiles(paths)
	if err != nil {
		return err
	}

	for fileIdx, file := range files {
		fmt.Printf("[%d/%d]: %v\n", fileIdx+1, len(files), file.path)
		includeLines := file.includesLineNumbers()
		enabled := make(map[int]bool, len(file.lines))
		for i := range file.lines {
			enabled[i] = true
		}
		for includeIdx, line := range includeLines {
			fmt.Printf("    [%d/%d]: %v", includeIdx+1, len(includeLines), file.lines[line])
			enabled[line] = false
			if err := file.save(enabled); err != nil {
				return err
			}
			ok, err := tryBuild()
			if err != nil {
				return err
			}
			if ok {
				fmt.Printf(" removed\n")
				// Wait a bit so file timestamps get an opportunity to change.
				// Attempting to save too soon after a successful build may
				// result in a false-positive build.
				time.Sleep(time.Second)
			} else {
				fmt.Printf(" required\n")
				enabled[line] = true
			}
		}
		if err := file.save(enabled); err != nil {
			return err
		}
		if err := file.format(); err != nil {
			return err
		}
		if err := file.stage(); err != nil {
			return err
		}
	}
	fmt.Println("Done")
	return nil
}

// Attempt to build the project. Returns true on successful build, false if
// there was a build failure.
func tryBuild() (bool, error) {
	cmd := exec.Command("sh", "-c", buildScript)
	out, err := cmd.CombinedOutput()
	switch err := err.(type) {
	case nil:
		return cmd.ProcessState.Success(), nil
	case *exec.ExitError:
		return false, nil
	default:
		return false, fmt.Errorf("Test failed with error: %v\n%v", err, string(out))
	}
}

type file struct {
	path  string
	lines []string
}

var includeRE = regexp.MustCompile(`^\s*#include (?:\"([^"]*)\"|:?\<([^"]*)\>)`)

// Returns the file path with the extension stripped
func stripExtension(path string) string {
	if dot := strings.IndexRune(path, '.'); dot > 0 {
		return path[:dot]
	}
	return path
}

// Returns the zero-based line numbers of all #include statements in the file
func (f *file) includesLineNumbers() []int {
	out := []int{}
	for i, l := range f.lines {
		matches := includeRE.FindStringSubmatch(l)
		if len(matches) == 0 {
			continue
		}

		include := matches[1]
		if include == "" {
			include = matches[2]
		}

		if strings.HasSuffix(stripExtension(f.path), stripExtension(include)) {
			// Don't remove #include for header of cc
			continue
		}

		out = append(out, i)
	}
	return out
}

// Saves the file, omitting the lines with the zero-based line number that are
// either not in `lines` or have a `false` value.
func (f *file) save(lines map[int]bool) error {
	content := []string{}
	for i, l := range f.lines {
		if lines[i] {
			content = append(content, l)
		}
	}
	data := []byte(strings.Join(content, "\n"))
	return ioutil.WriteFile(f.path, data, 0666)
}

// Runs clang-format on the file
func (f *file) format() error {
	err := exec.Command("clang-format", "-i", f.path).Run()
	if err != nil {
		return fmt.Errorf("Couldn't format file '%v': %w", f.path, err)
	}
	return nil
}

// Runs git add on the file
func (f *file) stage() error {
	err := exec.Command("git", "-C", projectRoot, "add", f.path).Run()
	if err != nil {
		return fmt.Errorf("Couldn't stage file '%v': %w", f.path, err)
	}
	return nil
}

// Loads all the files with the given file paths, splitting their content into
// into lines.
func loadFiles(paths []string) ([]file, error) {
	wg := sync.WaitGroup{}
	wg.Add(len(paths))
	files := make([]file, len(paths))
	errs := make([]error, len(paths))
	for i, path := range paths {
		i, path := i, filepath.Join(projectRoot, path)
		go func() {
			defer wg.Done()
			body, err := ioutil.ReadFile(path)
			if err != nil {
				errs[i] = fmt.Errorf("Failed to open %v: %w", path, err)
			} else {
				content := string(body)
				lines := strings.Split(content, "\n")
				files[i] = file{path: path, lines: lines}
			}
		}()
	}
	wg.Wait()
	for _, err := range errs {
		if err != nil {
			return nil, err
		}
	}
	return files, nil
}

// Returns the path to the directory holding this .go file
func getToolRoot() string {
	_, filename, _, ok := runtime.Caller(0)
	if !ok {
		panic("No caller information")
	}
	mainPath, err := filepath.Abs(filename)
	if err != nil {
		panic(err)
	}
	return filepath.Dir(mainPath)
}

// Returns the path to the project root
func getProjectRoot(toolRoot string) string {
	root, err := filepath.Abs(filepath.Join(toolRoot, "../.."))
	if err != nil {
		panic(err)
	}
	return root
}
