package scmauth

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	builder "github.com/openshift/builder/pkg/build/builder"
	utillog "github.com/openshift/builder/pkg/build/builder/util/log"
)

var log = utillog.ToFile(os.Stderr, 2)

// createGitConfig creates a git configuration file in a temporary directory, with an include
// section to the provided path.
// Returns the path to the git configuration file, and error if raised.
func createGitConfig(includePath string, context SCMAuthContext) (string, error) {
	tempDir, err := ioutil.TempDir("", "git")
	if err != nil {
		return "", err
	}
	gitconfig := filepath.Join(tempDir, ".gitconfig")
	content := fmt.Sprintf("[include]\npath = %s\n", includePath)
	if err := ioutil.WriteFile(gitconfig, []byte(content), 0600); err != nil {
		return "", err
	}
	// The GIT_CONFIG variable won't affect regular git operation
	// therefore the HOME variable needs to be set so git can pick up
	// .gitconfig from that location. The GIT_CONFIG variable is still used
	// to track the location of the GIT_CONFIG for multiple SCMAuth objects.
	if err := context.Set("HOME", tempDir); err != nil {
		return gitconfig, err
	}
	if err := context.Set("GIT_CONFIG", gitconfig); err != nil {
		return gitconfig, err
	}
	return gitconfig, nil
}

// ensureGitConfigIncludes ensures that the OS env var GIT_CONFIG is set and
// that it points to a file that has an include statement for the given path.
// Returns the location of the .gitconfig file, and error if raised.
func ensureGitConfigIncludes(path string, context SCMAuthContext) (string, error) {
	gitconfig, present := context.Get("GIT_CONFIG")
	if !present {
		return createGitConfig(path, context)
	}

	lines, err := builder.ReadLines(gitconfig)
	if err != nil {
		return gitconfig, err
	}
	for _, line := range lines {
		// If include already exists, return with no error
		if line == fmt.Sprintf("path = %s", path) {
			return gitconfig, nil
		}
	}

	lines = append(lines, fmt.Sprintf("path = %s", path))
	content := []byte(strings.Join(lines, "\n"))
	err = ioutil.WriteFile(gitconfig, content, 0600)
	return gitconfig, err
}
