// Copyright 2019 The Chromium OS 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 main

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

type command struct {
	Path string   `json:"path"`
	Args []string `json:"args"`
	// Updates and additions have the form:
	// `NAME=VALUE`
	// Removals have the form:
	// `NAME=`.
	EnvUpdates []string `json:"env_updates,omitempty"`
}

func newProcessCommand() *command {
	return &command{
		Path: os.Args[0],
		Args: os.Args[1:],
	}
}

func mergeEnvValues(values []string, updates []string) []string {
	envMap := map[string]string{}
	for _, entry := range values {
		equalPos := strings.IndexRune(entry, '=')
		envMap[entry[:equalPos]] = entry[equalPos+1:]
	}
	for _, update := range updates {
		equalPos := strings.IndexRune(update, '=')
		key := update[:equalPos]
		value := update[equalPos+1:]
		if value == "" {
			delete(envMap, key)
		} else {
			envMap[key] = value
		}
	}
	env := []string{}
	for key, value := range envMap {
		env = append(env, key+"="+value)
	}
	return env
}

func runCmd(env env, cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
	execCmd := exec.Command(cmd.Path, cmd.Args...)
	execCmd.Env = mergeEnvValues(env.environ(), cmd.EnvUpdates)
	execCmd.Dir = env.getwd()
	execCmd.Stdin = stdin
	execCmd.Stdout = stdout
	execCmd.Stderr = stderr
	return execCmd.Run()
}

func resolveAgainstPathEnv(env env, cmd string) (string, error) {
	path, _ := env.getenv("PATH")
	for _, path := range strings.Split(path, ":") {
		resolvedPath := filepath.Join(path, cmd)
		if _, err := os.Lstat(resolvedPath); err == nil {
			return resolvedPath, nil
		}
	}
	return "", fmt.Errorf("Couldn't find cmd %q in path", cmd)
}

func getAbsCmdPath(env env, cmd *command) string {
	path := cmd.Path
	if !filepath.IsAbs(path) {
		path = filepath.Join(env.getwd(), path)
	}
	return path
}

func newCommandBuilder(env env, cfg *config, cmd *command) (*commandBuilder, error) {
	basename := filepath.Base(cmd.Path)
	var nameParts []string
	if basename == "clang-tidy" {
		nameParts = []string{basename}
	} else {
		nameParts = strings.Split(basename, "-")
	}
	target := builderTarget{}
	switch len(nameParts) {
	case 1:
		// E.g. gcc
		target = builderTarget{
			compiler: nameParts[0],
		}
	case 4:
		// E.g. armv7m-cros-eabi-gcc
		target = builderTarget{
			arch:     nameParts[0],
			vendor:   nameParts[1],
			abi:      nameParts[2],
			compiler: nameParts[3],
			target:   basename[:strings.LastIndex(basename, "-")],
		}
	case 5:
		// E.g. x86_64-cros-linux-gnu-gcc
		target = builderTarget{
			arch:     nameParts[0],
			vendor:   nameParts[1],
			sys:      nameParts[2],
			abi:      nameParts[3],
			compiler: nameParts[4],
			target:   basename[:strings.LastIndex(basename, "-")],
		}
	default:
		return nil, newErrorwithSourceLocf("unexpected compiler name pattern. Actual: %s", basename)
	}

	var compilerType compilerType
	switch {
	case strings.HasPrefix(target.compiler, "clang-tidy"):
		compilerType = clangTidyType
	case strings.HasPrefix(target.compiler, "clang"):
		compilerType = clangType
	default:
		compilerType = gccType
	}
	target.compilerType = compilerType
	absWrapperPath, err := getAbsWrapperPath(env, cmd)
	if err != nil {
		return nil, err
	}
	rootPath := filepath.Join(filepath.Dir(absWrapperPath), cfg.rootRelPath)
	return &commandBuilder{
		path:           cmd.Path,
		args:           createBuilderArgs( /*fromUser=*/ true, cmd.Args),
		env:            env,
		cfg:            cfg,
		rootPath:       rootPath,
		absWrapperPath: absWrapperPath,
		target:         target,
	}, nil
}

type commandBuilder struct {
	path           string
	target         builderTarget
	args           []builderArg
	envUpdates     []string
	env            env
	cfg            *config
	rootPath       string
	absWrapperPath string
}

type builderArg struct {
	value    string
	fromUser bool
}

type compilerType int32

const (
	gccType compilerType = iota
	clangType
	clangTidyType
)

type builderTarget struct {
	target       string
	arch         string
	vendor       string
	sys          string
	abi          string
	compiler     string
	compilerType compilerType
}

func createBuilderArgs(fromUser bool, args []string) []builderArg {
	builderArgs := make([]builderArg, len(args))
	for i, arg := range args {
		builderArgs[i] = builderArg{value: arg, fromUser: fromUser}
	}
	return builderArgs
}

func (builder *commandBuilder) clone() *commandBuilder {
	return &commandBuilder{
		path:           builder.path,
		args:           append([]builderArg{}, builder.args...),
		env:            builder.env,
		cfg:            builder.cfg,
		rootPath:       builder.rootPath,
		target:         builder.target,
		absWrapperPath: builder.absWrapperPath,
	}
}

func (builder *commandBuilder) wrapPath(path string, extraFlags ...string) {
	newArgs := createBuilderArgs( /*fromUser=*/ false, extraFlags)
	newArgs = append(newArgs, builderArg{value: builder.path, fromUser: false})
	builder.args = append(newArgs, builder.args...)
	builder.path = path
}

func (builder *commandBuilder) addPreUserArgs(args ...string) {
	index := 0
	for _, arg := range builder.args {
		if arg.fromUser {
			break
		}
		index++
	}
	builder.args = append(builder.args[:index], append(createBuilderArgs( /*fromUser=*/ false, args), builder.args[index:]...)...)
}

func (builder *commandBuilder) addPostUserArgs(args ...string) {
	builder.args = append(builder.args, createBuilderArgs( /*fromUser=*/ false, args)...)
}

// Allows to map and filter arguments. Filters when the callback returns an empty string.
func (builder *commandBuilder) transformArgs(transform func(arg builderArg) string) {
	// See https://github.com/golang/go/wiki/SliceTricks
	newArgs := builder.args[:0]
	for _, arg := range builder.args {
		newArg := transform(arg)
		if newArg != "" {
			newArgs = append(newArgs, builderArg{
				value:    newArg,
				fromUser: arg.fromUser,
			})
		}
	}
	builder.args = newArgs
}

func (builder *commandBuilder) updateEnv(updates ...string) {
	builder.envUpdates = append(builder.envUpdates, updates...)
}

func (builder *commandBuilder) build() *command {
	cmdArgs := make([]string, len(builder.args))
	for i, builderArg := range builder.args {
		cmdArgs[i] = builderArg.value
	}
	return &command{
		Path:       builder.path,
		Args:       cmdArgs,
		EnvUpdates: builder.envUpdates,
	}
}
