// Copyright 2017 The Fuchsia 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 project

import (
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"runtime"
	"sort"
	"strings"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
	"go.fuchsia.dev/jiri/osutil"
	"go.fuchsia.dev/jiri/retry"
)

func isFile(file string) (bool, error) {
	fileInfo, err := os.Stat(file)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, fmtError(err)
	}
	return !fileInfo.IsDir(), nil
}

func fmtError(err error) error {
	if err == nil {
		return nil
	}
	_, file, line, _ := runtime.Caller(1)
	return fmt.Errorf("%s:%d: %s", filepath.Base(file), line, err)
}

func SafeWriteFile(jirix *jiri.X, filename string, data []byte) error {
	tmp := filename + ".tmp"
	if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
		return fmtError(err)
	}
	if err := os.WriteFile(tmp, data, 0644); err != nil {
		return fmtError(err)
	}
	return fmtError(osutil.Rename(tmp, filename))
}

func isPathDir(dir string) bool {
	if dir != "" {
		if fi, err := os.Stat(dir); err == nil {
			return fi.IsDir()
		}
	}
	return false
}

func isEmpty(path string) (bool, error) {
	dir, err := os.Open(path)
	if err != nil {
		return false, fmtError(err)
	}
	defer dir.Close()

	if _, err = dir.Readdirnames(1); err != nil && err == io.EOF {
		return true, nil
	} else {
		return false, fmtError(err)
	}
}

// fmtRevision returns the first 8 chars of a revision hash.
func fmtRevision(r string) string {
	l := 8
	if len(r) < l {
		return r
	}
	return r[:l]
}

// clone is a wrapper that reattempts a git clone operation on failure.
func clone(jirix *jiri.X, repo, path string, opts ...gitutil.CloneOpt) error {
	msg := fmt.Sprintf("Cloning %s", repo)
	t := jirix.Logger.TrackTime(msg)
	defer t.Done()
	return retry.Function(jirix, func() error {
		return gitutil.New(jirix).Clone(repo, path, opts...)
	}, msg, retry.AttemptsOpt(jirix.Attempts))
}

// fetch is a wrapper that reattempts a git fetch operation on failure.
func fetch(jirix *jiri.X, path, remote string, opts ...gitutil.FetchOpt) error {
	msg := fmt.Sprintf("Fetching for %s", path)
	t := jirix.Logger.TrackTime(msg)
	defer t.Done()
	return retry.Function(jirix, func() error {
		return gitutil.New(jirix, gitutil.RootDirOpt(path)).Fetch(remote, jirix.EnableSubmodules, opts...)
	}, msg, retry.AttemptsOpt(jirix.Attempts))
}

type MultiError []error

func (m MultiError) Error() string {
	s := []string{}
	n := 0
	for _, e := range m {
		if e != nil {
			s = append(s, e.Error())
			n++
		}
	}
	sort.Strings(s)
	switch n {
	case 0:
		return "(0 errors)"
	case 1:
		return s[0]
	case 2:
		return s[0] + " (and 1 other error not shown here)"
	}
	return fmt.Sprintf("%s (and %d other errors not shown here)", s[0], n-1)
}

// WriteGitExcludeFile adds file to .git/info/exclude. Check if it exists already first.
func WriteGitExcludeFile(jirix *jiri.X, files []string, tag string) error {
	// If the file doesn't exist, create it, or append to the file
	gitExclude := filepath.Join(jirix.Root, ".git/info/exclude")
	var gitData []byte
	if _, err := os.Stat(gitExclude); err == nil {
		if gitData, err = os.ReadFile(gitExclude); err != nil {
			return err
		}
	}
	s := string(gitData)
	// Make path start from root of checkout, and end with new line.
	for i, v := range files {
		files[i] = fmt.Sprintf("/%s\n", v)
	}
	fileString := strings.Join(files, "")
	beginTag := fmt.Sprintf("# BEGIN jiri %s\n", tag)
	endTag := fmt.Sprintf("# END jiri %s\n", tag)
	m := regexp.MustCompile(fmt.Sprintf("(?s)%s(.*)%s", beginTag, endTag))
	data := fmt.Sprintf("%s%s%s", beginTag, fileString, endTag)
	if strings.Contains(s, beginTag) {
		s = m.ReplaceAllString(s, data)
	} else {
		if strings.HasSuffix(s, "\n") || (s == "") {
			s = fmt.Sprintf("%s%s", s, data)
		} else {
			s = fmt.Sprintf("%s\n%s", s, data)
		}
	}
	return SafeWriteFile(jirix, gitExclude, []byte(s))
}
