package buildskia

import (
	"context"
	"errors"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"time"

	"go.skia.org/infra/go/metrics2"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/go/vcsinfo"
)

const (
	GOOD_BUILDS_FILENAME = "goodbuilds.txt"

	// PRESERVE_DURATION is used to determine if an LKGR commit should be
	// preserved.  i.e. if a the distance between two commits is greater than
	// PRESERVER_DURATION then they both should be preserved.
	PRESERVE_DURATION = 30 * 24 * time.Hour

	// DECIMATION_PERIOD is the time between decimation runs.
	DECIMATION_PERIOD = time.Hour

	// BUILD_TYPE is the type of build we use throughout.
	BUILD_TYPE = RELEASE_BUILD
)

// errors
var (
	AlreadyExistsErr = errors.New("Checkout already exists.")
)

// PerBuild is a callback function where ContinuousBuilder clients can
// perform specific builds within the newest Skia checkout.
type PerBuild func(ctx context.Context, checkout, depotTools string) error

// ContinuousBuilder is for building versions of the Skia library and then compiling and
// running command-line apps against those built versions.
//
// For each LKGR of Skia, that version of code will be checked out under
// workDir/"versions"/<git hash>.
type ContinuousBuilder struct {
	workRoot   string
	depotTools string
	repo       vcsinfo.VCS
	perBuild   PerBuild
	preserve   int
	useGn      bool

	buildFailures    metrics2.Counter
	buildLiveness    metrics2.Liveness
	repoSyncFailures metrics2.Counter

	timeBetweenBuilds time.Duration

	// hashes is a cache of the hashes returned from Available.
	hashes []string

	// current is the current commit we are building at.
	current *vcsinfo.LongCommit

	// mutex protects access to hashes, current, and GOOD_BUILDS_FILENAME.
	mutex sync.Mutex
}

// New returns a new ContinuousBuilder instance.
//
//	workRoot - The root directory where work is stored.
//	depotTools - The directory where depot_tools is checked out.
//	repo - A vcs to pull hash info from.
//	perBuild - A PerBuild callback that gets called every time a new successful build of Skia is available.
//	preserve - The number of LKGR builds to preserve after decimation.
//	timeBetweenBuilds - The duration between attempts to pull LGKR and built it.
//	useGn - Use GN as the meta build system, as opposed to GYP.
//
// Call Start() to begin the continous build Go routine.
func New(ctx context.Context, workRoot, depotTools string, repo vcsinfo.VCS, perBuild PerBuild, preserve int, timeBetweenBuilds time.Duration, useGn bool) *ContinuousBuilder {
	b := &ContinuousBuilder{
		workRoot:          workRoot,
		depotTools:        depotTools,
		repo:              repo,
		perBuild:          perBuild,
		preserve:          preserve,
		buildFailures:     metrics2.GetCounter("builds_failed", nil),
		buildLiveness:     metrics2.NewLiveness("build"),
		repoSyncFailures:  metrics2.GetCounter("repo_sync_failed", nil),
		timeBetweenBuilds: timeBetweenBuilds,
		useGn:             useGn,
	}
	_, _ = b.AvailableBuilds() // Called for side-effect of loading hashes.
	go b.startDecimation(ctx)
	b.updateCurrent(ctx)

	return b
}

func (b *ContinuousBuilder) singleBuildLatest(ctx context.Context) {
	if err := b.repo.Update(ctx, true, true); err != nil {
		sklog.Errorf("Failed to update skia repo used to look up git hashes: %s", err)
		b.repoSyncFailures.Inc(1)
	}
	b.repoSyncFailures.Reset()
	ci, err := b.BuildLatestSkia(ctx, false, true, false)
	if err != nil {
		sklog.Errorf("Failed to build LKGR: %s", err)
		// Only measure real build failures, not a failure if LKGR hasn't updated.
		if err != AlreadyExistsErr {
			b.buildFailures.Inc(1)
		}
		return
	}
	b.buildFailures.Reset()
	b.buildLiveness.Reset()
	sklog.Infof("Successfully built: %s %s", ci.Hash, ci.Subject)
}

// Start the continuous build latest LKGR Go routine.
func (b *ContinuousBuilder) Start(ctx context.Context) {
	go func() {
		b.singleBuildLatest(ctx)
		for range time.Tick(b.timeBetweenBuilds) {
			b.singleBuildLatest(ctx)
		}
	}()
}

// prepDirectory adds the 'versions' directory to the workRoot
// and returns the full path of that directory.
func prepDirectory(workRoot string) (string, error) {
	versions := path.Join(workRoot, "versions")
	if err := os.MkdirAll(versions, 0777); err != nil {
		return "", fmt.Errorf("Failed to create WORK_ROOT/versions dir: %s", err)
	}
	return versions, nil
}

// BuildLatestSkia builds the LKGR of Skia in the given workRoot directory.
//
// The library will be checked out into workRoot + "/" + githash, where githash
// is the githash of the LKGR of Skia.
//
//	force - If true then checkout and build even if the directory already exists.
//	head - If true then build Skia at HEAD, otherwise build Skia at LKGR.
//	deps - If true then install Skia dependencies.
//
// Returns the commit info for the revision of Skia checked out.
// Returns an error if any step fails, or return AlreadyExistsErr if
// the target checkout directory already exists and force is false.
//
// In GN mode ninja files are not generated, the caller must call GNGen
// in their PerBuild callback before calling GNNinjaBuild.
func (b *ContinuousBuilder) BuildLatestSkia(ctx context.Context, force bool, head bool, deps bool) (*vcsinfo.LongCommit, error) {
	versions, err := prepDirectory(b.workRoot)
	if err != nil {
		return nil, err
	}

	githash := ""
	if head {
		if githash, err = GetSkiaHead(nil); err != nil {
			return nil, fmt.Errorf("Failed to retrieve Skia HEAD: %s", err)
		}
	} else {
		if githash, err = GetSkiaHash(nil); err != nil {
			return nil, fmt.Errorf("Failed to retrieve Skia LKGR: %s", err)
		}
	}
	checkout := path.Join(versions, githash)

	fi, err := os.Stat(checkout)
	// If the file is present and a directory then only proceed if 'force' is true.
	if err == nil && fi.IsDir() == true && !force {
		sklog.Infof("Dir already exists: %s", checkout)
		return nil, AlreadyExistsErr
	}

	var ret *vcsinfo.LongCommit
	if b.useGn {
		ret, err = GNDownloadSkia(ctx, "", githash, checkout, b.depotTools, false, deps)
		if err != nil {
			return nil, fmt.Errorf("Failed to fetch: %s", err)
		}
	} else {
		ret, err = DownloadSkia(ctx, "", githash, checkout, b.depotTools, false, deps)
		if err != nil {
			return nil, fmt.Errorf("Failed to fetch: %s", err)
		}
	}

	if b.perBuild != nil {
		if err := b.perBuild(ctx, checkout, b.depotTools); err != nil {
			return nil, err
		}
	}
	b.mutex.Lock()
	defer b.mutex.Unlock()
	b.hashes = append(b.hashes, githash)
	b.updateCurrent(ctx)
	fb, err := os.OpenFile(filepath.Join(b.workRoot, GOOD_BUILDS_FILENAME), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		return nil, fmt.Errorf("Failed to open %s for writing: %s", GOOD_BUILDS_FILENAME, err)
	}
	defer util.Close(fb)
	_, err = fmt.Fprintf(fb, "%s\n", githash)
	if err != nil {
		return nil, fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FILENAME, err)
	}
	return ret, nil
}

// updateCurrent updates the value of b.current with the new gitinfo for the most recent build.
//
// Or a mildly informative stand-in if somehow the update fails.
//
// updateCurrent presumes the caller already has a lock on the mutex.
func (b *ContinuousBuilder) updateCurrent(ctx context.Context) {
	fallback := &vcsinfo.LongCommit{ShortCommit: &vcsinfo.ShortCommit{Hash: "unknown"}}
	if len(b.hashes) == 0 {
		sklog.Errorf("There are no hashes.")
		if b.current == nil {
			b.current = fallback
		}
		return
	}
	details, err := b.repo.Details(ctx, b.hashes[len(b.hashes)-1], false)
	if err != nil {
		sklog.Errorf("Unable to retrieve build info: %s", err)
		if b.current == nil {
			b.current = fallback
		}
		return
	}
	b.current = details
}

// AvailableBuilds returns a list of git hashes, all the versions of Skia that
// can be built against. This returns the list with the newest builds last.
// The list will always be of length > 1, otherwise and error is returned.
func (b *ContinuousBuilder) AvailableBuilds() ([]string, error) {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	if len(b.hashes) > 0 {
		return b.hashes, nil
	}
	fi, err := os.Open(filepath.Join(b.workRoot, GOOD_BUILDS_FILENAME))
	if err != nil {
		return nil, fmt.Errorf("Failed to open %s for reading: %s", GOOD_BUILDS_FILENAME, err)
	}
	defer util.Close(fi)
	buf, err := io.ReadAll(fi)
	if err != nil {
		return nil, fmt.Errorf("Failed to read: %s", err)
	}
	hashes := strings.Split(string(buf), "\n")
	realHashes := []string{}
	for _, h := range hashes {
		if h != "" {
			realHashes = append(realHashes, h)
		}
	}
	b.hashes = realHashes
	if len(b.hashes) == 0 {
		return nil, fmt.Errorf("List of available builds is empty.")
	}
	return realHashes, nil
}

func (b *ContinuousBuilder) Current() *vcsinfo.LongCommit {
	b.mutex.Lock()
	defer b.mutex.Unlock()
	return b.current
}

func (b *ContinuousBuilder) writeNewGoodBuilds(hashes []string) error {
	if len(hashes) < 1 {
		return fmt.Errorf("At least one good build must be kept around.")
	}
	b.mutex.Lock()
	defer b.mutex.Unlock()

	b.hashes = hashes
	fb, err := os.Create(filepath.Join(b.workRoot, GOOD_BUILDS_FILENAME))
	if err != nil {
		return fmt.Errorf("Failed to open %s for writing: %s", GOOD_BUILDS_FILENAME, err)
	}
	defer util.Close(fb)
	if _, err := fb.Write([]byte(strings.Join(hashes, "\n") + "\n")); err != nil {
		return fmt.Errorf("Failed to write %s: %s", GOOD_BUILDS_FILENAME, err)
	}
	return nil
}

func (b *ContinuousBuilder) startDecimation(ctx context.Context) {
	decimateLiveness := metrics2.NewLiveness("decimate")
	decimateFailures := metrics2.GetCounter("decimate_failed", nil)
	for range time.Tick(DECIMATION_PERIOD) {
		hashes, err := b.AvailableBuilds()
		if err != nil {
			sklog.Errorf("Failed to get available builds while decimating: %s", err)
			decimateFailures.Inc(1)
			continue
		}
		keep, remove, err := decimate(ctx, hashes, b.repo, b.preserve)
		if err != nil {
			sklog.Errorf("Failed to calc removals while decimating: %s", err)
			decimateFailures.Inc(1)
			continue
		}
		sklog.Infof("Decimate: Keep %v Remove %v", keep, remove)
		for _, hash := range remove {
			sklog.Infof("Decimate: Beginning %s", hash)
			if err := os.RemoveAll(filepath.Join(b.workRoot, "versions", hash)); err != nil {
				sklog.Errorf("Failed to remove directory for %s: %s", hash, err)
				continue
			}
			sklog.Infof("Decimate: Finished %s", hash)
		}
		if err := b.writeNewGoodBuilds(keep); err != nil {
			continue
		}
		decimateFailures.Reset()
		decimateLiveness.Reset()
	}
}

// decimate returns a list of hashes to keep, the list to remove,
// and an error if one occurred.
//
// The algorithm is:
//
//	Preserve all hashes that are spaced one month apart.
//	Then if there are more than 'limit' remaining hashes
//	remove every other one to bring the count down to 'limit'/2.
func decimate(ctx context.Context, hashes []string, vcs vcsinfo.VCS, limit int) ([]string, []string, error) {
	keep := []string{}
	remove := []string{}

	// The hashes are stored with the oldest first, newest last.
	// So we start at the front and work forward until we start to find hashes that are less than
	// PRESERVE_DURATION apart. Once we find that spot set oldiesEnd
	// to that index.
	oldiesEnd := 0
	c, err := vcs.Details(ctx, hashes[0], false)
	if err != nil {
		return nil, nil, fmt.Errorf("Failed to get hash details: %s", err)
	}
	lastTS := time.Time{}
	for i, h := range hashes {
		c, err = vcs.Details(ctx, h, false)
		if err != nil {
			return nil, nil, fmt.Errorf("Failed to get hash details: %s", err)
		}
		fmt.Printf("%v", c.Timestamp.Sub(lastTS))
		if c.Timestamp.Sub(lastTS) < PRESERVE_DURATION {
			break
		}
		lastTS = c.Timestamp
		oldiesEnd = i
	}

	// Now that we know where the old hashes that we want to preserve are, we
	// will chop them off and ignore them for the rest of the decimation process.
	oldies := hashes[:oldiesEnd]
	hashes = hashes[oldiesEnd:]
	fmt.Println(oldies, hashes)

	// Only do decimation if we have enough fresh hashes.
	if len(hashes) < limit {
		return append(oldies, hashes...), remove, nil
	}
	last := hashes[len(hashes)-1]
	for i, h := range hashes[:len(hashes)-1] {
		if i%2 == 0 {
			keep = append(keep, h)
		} else {
			remove = append(remove, h)
		}
	}
	keep = append(keep, last)
	// Once done with decimation add the oldies back into the list of hashes to keep.
	return append(oldies, keep...), remove, nil
}
