// Copyright 2021 Google LLC
//
// 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.

// Package gocmd provides helers for invoking Go tooling.
package gocmd

import (
	"errors"
	"fmt"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"cloud.google.com/go/internal/gapicgen/execv"
)

var (
	// ErrBuildConstraint is returned when the Go command returns this error.
	ErrBuildConstraint error = errors.New("build constraints exclude all Go files")
)

// ModTidy tidies go.mod file in the specified directory
func ModTidy(dir string) error {
	log.Printf("[%s] running go mod tidy", dir)
	c := execv.Command("go", "mod", "tidy")
	c.Dir = dir
	c.Env = []string{
		fmt.Sprintf("PATH=%s", os.Getenv("PATH")), // TODO(deklerk): Why do we need to do this? Doesn't seem to be necessary in other exec.Commands.
		fmt.Sprintf("HOME=%s", os.Getenv("HOME")), // TODO(deklerk): Why do we need to do this? Doesn't seem to be necessary in other exec.Commands.
	}
	return c.Run()
}

// ModTidyAll tidies all mod files from the specified root directory.
func ModTidyAll(dir string) error {
	log.Printf("[%s] finding all modules", dir)
	var modDirs []string
	err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.Name() == "go.mod" {
			modDirs = append(modDirs, filepath.Dir(path))
		}
		return nil
	})
	if err != nil {
		return err
	}
	for _, modDir := range modDirs {
		if err := ModTidy(modDir); err != nil {
			return err
		}
	}
	return nil
}

// ListModName finds a modules name for a given directory.
func ListModName(dir string) (string, error) {
	modC := execv.Command("go", "list", "-m")
	modC.Dir = dir
	mod, err := modC.Output()
	return string(mod), err
}

// ListModDirName finds the directory in which the module resides. Returns
// ErrBuildConstraint if all files in a module are constrained.
func ListModDirName(dir string) (string, error) {
	var out []byte
	var err error
	c := execv.Command("go", "list", "-f", "'{{.Module.Dir}}'")
	c.Dir = dir
	if out, err = c.Output(); err != nil {
		if ee, ok := err.(*exec.ExitError); ok {
			if strings.Contains(string(ee.Stderr), "build constraints exclude all Go files") {
				return "", ErrBuildConstraint
			}
		}
		return "", err
	}
	return strings.Trim(strings.TrimSpace(string(out)), "'"), nil
}

// Build attempts to build all packages recursively from the given directory.
func Build(dir string) error {
	log.Println("building generated code")
	c := execv.Command("go", "build", "./...")
	c.Dir = dir
	if _, err := c.Output(); err != nil {
		if ee, ok := err.(*exec.ExitError); ok {
			log.Printf("Error Output: %s", ee.Stderr)
		}
		return err
	}
	return nil
}

// Vet runs linters on all .go files recursively from the given directory.
func Vet(dir string) error {
	log.Println("vetting generated code")
	c := execv.Command("goimports", "-w", ".")
	c.Dir = dir
	if err := c.Run(); err != nil {
		return err
	}

	c = execv.Command("gofmt", "-s", "-d", "-w", "-l", ".")
	c.Dir = dir
	return c.Run()
}

// CurrentMod returns the module name of the provided directory.
func CurrentMod(dir string) (string, error) {
	log.Println("detecting current module")
	c := execv.Command("go", "list", "-m")
	c.Dir = dir
	var out []byte
	var err error
	if out, err = c.Output(); err != nil {
		return "", err
	}
	return strings.TrimSpace(string(out)), nil
}
