// Copyright 2019 The ChromiumOS 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"
	"os/exec"
	"runtime"
	"strings"
	"syscall"
)

type userError struct {
	err string
}

var _ error = userError{}

func (err userError) Error() string {
	return err.err
}

func newUserErrorf(format string, v ...interface{}) userError {
	return userError{err: fmt.Sprintf(format, v...)}
}

func newErrorwithSourceLocf(format string, v ...interface{}) error {
	return newErrorwithSourceLocfInternal(2, format, v...)
}

func wrapErrorwithSourceLocf(err error, format string, v ...interface{}) error {
	return newErrorwithSourceLocfInternal(2, "%s: %s", fmt.Sprintf(format, v...), err.Error())
}

func wrapSubprocessErrorWithSourceLoc(cmd *command, subprocessErr error) (exitCode int, err error) {
	if subprocessErr == nil {
		return 0, nil
	}
	if userErr, ok := getCCacheError(cmd, subprocessErr); ok {
		return 0, userErr
	}
	if exitCode, ok := getExitCode(subprocessErr); ok {
		return exitCode, nil
	}
	err = newErrorwithSourceLocfInternal(2, "failed to execute %#v: %s", cmd, subprocessErr)
	return 0, err
}

// Based on the implementation of log.Output
func newErrorwithSourceLocfInternal(skip int, format string, v ...interface{}) error {
	_, file, line, ok := runtime.Caller(skip)
	if !ok {
		file = "???"
		line = 0
	}
	if lastSlash := strings.LastIndex(file, "/"); lastSlash >= 0 {
		file = file[lastSlash+1:]
	}

	return fmt.Errorf("%s:%d: %s", file, line, fmt.Sprintf(format, v...))
}

func getExitCode(err error) (exitCode int, ok bool) {
	if err == nil {
		return 0, true
	}
	if exiterr, ok := err.(*exec.ExitError); ok {
		if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
			return status.ExitStatus(), true
		}
	}
	return 0, false
}

func getCCacheError(compilerCmd *command, compilerCmdErr error) (ccacheErr userError, ok bool) {
	if en, ok := compilerCmdErr.(syscall.Errno); ok && en == syscall.ENOENT &&
		strings.Contains(compilerCmd.Path, "ccache") {
		ccacheErr =
			newUserErrorf("ccache not found under %s. Please install it",
				compilerCmd.Path)
		return ccacheErr, true
	}
	return ccacheErr, false
}
