// Copyright 2017 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package venv

import (
	"context"

	"github.com/danjacques/gofslock/fslock"

	"go.chromium.org/luci/common/clock"
	"go.chromium.org/luci/common/data/stringset"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/logging"
)

// pruneReadDirSize is the number of entries to read in a directory at a time
// when pruning.
const pruneReadDirSize = 128

// prune examines environments in cfg's BaseDir. If any are found that are older
// than the prune threshold in "cfg", they will be safely deleted.
//
// If exempt is not nil, it contains a list of VirtualEnv names that will be
// exempted from pruning. This is used to prevent pruning from modifying
// environments that are known to be recently used, and to completely avoid a
// case where an environment could be pruned while it's in use by this program.
func prune(c context.Context, cfg *Config, exempt stringset.Set) error {
	pruneThreshold := cfg.PruneThreshold
	if pruneThreshold <= 0 {
		// Pruning is disabled.
		return nil
	}

	now := clock.Now(c)
	minPruneAge := now.Add(-pruneThreshold)

	// Run a series of independent scan/prune operations.
	logging.Debugf(c, "Pruning entries in [%s] older than %s (%s).", cfg.BaseDir, pruneThreshold, minPruneAge)

	// Iterate over all of our VirtualEnv candidates.
	//
	// Any pruning errors will be accumulated in "allErrs", so ForEach will only
	// receive nil return values from the callback. This means that any error
	// returned by ForEach was an actual error with the iteration itself.
	var (
		allErrs     errors.MultiError
		totalPruned = 0
		hitLimitStr = ""
	)

	// We need to cancel if we hit our prune limit.
	c, cancelFunc := context.WithCancel(c)
	defer cancelFunc()

	// Iterate over all VirtualEnv directories, regardless of their completion
	// status.
	it := Iterator{
		// Shuffle the slice randomly. We do this in case others are also processing
		// this directory simultaneously.
		Shuffle: true,
	}
	err := it.ForEach(c, cfg, func(c context.Context, e *Env) error {
		if exempt != nil && exempt.Has(e.Name) {
			logging.Debugf(c, "Not pruning currently in-use environment: %s", e.Name)
			return nil
		}

		if ts, err := e.completionFlagTimestamp(); err == nil && ts.After(minPruneAge) {
			logging.Debugf(c, "Environment [%s] is younger than minimum prune age (%s).", e.Name, ts)
			return nil
		}

		switch err := e.Delete(c); errors.Unwrap(err) {
		case nil:
			totalPruned++
			if cfg.MaxPrunesPerSweep > 0 && totalPruned >= cfg.MaxPrunesPerSweep {
				logging.Debugf(c, "Hit prune limit of %d.", cfg.MaxPrunesPerSweep)
				hitLimitStr = " (limit)"
				cancelFunc()
			}

		case fslock.ErrLockHeld:
			logging.WithError(err).Debugf(c, "Environment [%s] is in use.", e.Name)

		default:
			err = errors.Annotate(err, "failed to prune file: %s", e.Name).
				InternalReason("dir(%q)", e.Config.BaseDir).Err()
			allErrs = append(allErrs, err)
		}
		return nil
	})
	if err != nil {
		// Error during iteration.
		return err
	}

	logging.Infof(c, "Pruned %d environment(s)%s with %d error(s)", totalPruned, hitLimitStr, len(allErrs))
	if len(allErrs) > 0 {
		return allErrs
	}
	return nil
}
