// 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"
	"path/filepath"
)

func callCompiler(env env, cfg *config, inputCmd *command) int {
	exitCode := 0
	var compilerErr error
	if cfg.oldWrapperPath != "" {
		exitCode, compilerErr = callCompilerWithRunAndCompareToOldWrapper(env, cfg, inputCmd)
	} else {
		exitCode, compilerErr = callCompilerInternal(env, cfg, inputCmd)
	}
	if compilerErr != nil {
		printCompilerError(env.stderr(), compilerErr)
		exitCode = 1
	}
	return exitCode
}

func callCompilerWithRunAndCompareToOldWrapper(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
	recordingEnv := &commandRecordingEnv{
		env: env,
	}
	// Note: this won't do a real exec as recordingEnv redirects exec to run.
	if exitCode, err = callCompilerInternal(recordingEnv, cfg, inputCmd); err != nil {
		return 0, err
	}
	if err = compareToOldWrapper(env, cfg, inputCmd, recordingEnv.cmdResults, exitCode); err != nil {
		return exitCode, err
	}
	return exitCode, nil
}

func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
	if err := checkUnsupportedFlags(inputCmd); err != nil {
		return 0, err
	}
	mainBuilder, err := newCommandBuilder(env, cfg, inputCmd)
	if err != nil {
		return 0, err
	}
	processPrintConfigFlag(mainBuilder)
	processPrintCmdlineFlag(mainBuilder)
	env = mainBuilder.env
	var compilerCmd *command
	clangSyntax := processClangSyntaxFlag(mainBuilder)
	if mainBuilder.target.compilerType == clangType {
		cSrcFile, useClangTidy := processClangTidyFlags(mainBuilder)
		sysroot, err := prepareClangCommand(mainBuilder)
		if err != nil {
			return 0, err
		}
		allowCCache := true
		if useClangTidy {
			allowCCache = false
			clangCmdWithoutGomaAndCCache := mainBuilder.build()
			if err := runClangTidy(env, clangCmdWithoutGomaAndCCache, cSrcFile); err != nil {
				return 0, err
			}
		}
		processGomaCCacheFlags(sysroot, allowCCache, mainBuilder)
		compilerCmd = mainBuilder.build()
	} else {
		if clangSyntax {
			allowCCache := false
			clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
			if err != nil {
				return 0, err
			}
			exitCode, err = checkClangSyntax(env, clangCmd)
			if err != nil || exitCode != 0 {
				return exitCode, err
			}
		}
		compilerCmd = calcGccCommand(mainBuilder)
	}
	rusageLogfileName := getRusageLogFilename(env)
	bisectStage := getBisectStage(env)
	if shouldForceDisableWError(env) {
		if rusageLogfileName != "" {
			return 0, newUserErrorf("GETRUSAGE is meaningless with FORCE_DISABLE_WERROR")
		}
		if bisectStage != "" {
			return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
		}
		return doubleBuildWithWNoError(env, cfg, compilerCmd)
	}
	if rusageLogfileName != "" {
		if bisectStage != "" {
			return 0, newUserErrorf("BISECT_STAGE is meaningless with GETRUSAGE")
		}
		return logRusage(env, rusageLogfileName, compilerCmd)
	}
	if bisectStage != "" {
		compilerCmd = calcBisectCommand(env, bisectStage, compilerCmd)
	}
	// Note: We return an exit code only if the underlying env is not
	// really doing an exec, e.g. commandRecordingEnv.
	return wrapSubprocessErrorWithSourceLoc(compilerCmd, env.exec(compilerCmd))
}

func prepareClangCommand(builder *commandBuilder) (sysroot string, err error) {
	sysroot = ""
	if !builder.cfg.isHostWrapper {
		sysroot = processSysrootFlag(builder)
	}
	builder.addPreUserArgs(builder.cfg.clangFlags...)
	calcCommonPreUserArgs(builder)
	if err := processClangFlags(builder); err != nil {
		return "", err
	}
	return sysroot, nil
}

func calcClangCommand(allowCCache bool, builder *commandBuilder) (*command, error) {
	sysroot, err := prepareClangCommand(builder)
	if err != nil {
		return nil, err
	}
	processGomaCCacheFlags(sysroot, allowCCache, builder)
	return builder.build(), nil
}

func calcGccCommand(builder *commandBuilder) *command {
	sysroot := ""
	if !builder.cfg.isHostWrapper {
		sysroot = processSysrootFlag(builder)
	}
	builder.addPreUserArgs(builder.cfg.gccFlags...)
	if !builder.cfg.isHostWrapper {
		calcCommonPreUserArgs(builder)
	}
	processGccFlags(builder)
	if !builder.cfg.isHostWrapper {
		allowCCache := true
		processGomaCCacheFlags(sysroot, allowCCache, builder)
	}
	return builder.build()
}

func calcCommonPreUserArgs(builder *commandBuilder) {
	builder.addPreUserArgs(builder.cfg.commonFlags...)
	if !builder.cfg.isHostWrapper {
		processPieFlags(builder)
		processStackProtectorFlags(builder)
		processThumbCodeFlags(builder)
		processX86Flags(builder)
	}
	processSanitizerFlags(builder)
}

func processGomaCCacheFlags(sysroot string, allowCCache bool, builder *commandBuilder) {
	gomaccUsed := false
	if !builder.cfg.isHostWrapper {
		gomaccUsed = processGomaCccFlags(builder)
	}
	if !gomaccUsed && allowCCache {
		processCCacheFlag(sysroot, builder)
	}
}

func getAbsWrapperPath(env env, wrapperCmd *command) (string, error) {
	wrapperPath := getAbsCmdPath(env, wrapperCmd)
	evaledCmdPath, err := filepath.EvalSymlinks(wrapperPath)
	if err != nil {
		return "", wrapErrorwithSourceLocf(err, "failed to evaluate symlinks for %s", wrapperPath)
	}
	return evaledCmdPath, nil
}

func printCompilerError(writer io.Writer, compilerErr error) {
	if _, ok := compilerErr.(userError); ok {
		fmt.Fprintf(writer, "%s\n", compilerErr)
	} else {
		fmt.Fprintf(writer,
			"Internal error. Please report to chromeos-toolchain@google.com.\n%s\n",
			compilerErr)
	}
}
