// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The following enables go generate to generate the doc.go file.
//go:generate go run $V23_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go .

package main

import (
	"fmt"
	"sort"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/set"
	"v.io/x/lib/vlog"
	"v.io/x/ref/lib/v23cmd"
	_ "v.io/x/ref/runtime/factories/generic"
	"v.io/x/ref/services/internal/binarylib"
	"v.io/x/ref/services/internal/profiles"
	"v.io/x/ref/services/repository"
)

var cmdBinaryTidy = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runBinaryTidy),
	Name:   "binary",
	Short:  "Binary sub-command tidies a specified binaryd",
	Long: `
Binary sub-command removes all binaries from a specified binaryd that
are not referenced by an applicationd envelope stored in the specified
applicationd.
`,
	ArgsName: "<applicationd> <binaryd>",
	ArgsLong: `
<applicationd> is the name or endpoint of the applicationd instance
sourcing the envelopes.
<binaryd> is the name or endpoint of a binaryd instance to clean up.
`,
}

// simpleGlob globs the provided endpoint as the namespace cmd does.
func mapGlob(ctx *context.T, pattern string, mapFunc func(string)) (error, []error) {
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()

	ns := v23.GetNamespace(ctx)
	c, err := ns.Glob(ctx, pattern)
	if err != nil {
		vlog.Infof("ns.Glob(%q) failed: %v", pattern, err)
		return err, nil
	}

	errors := []*naming.GlobError{}
	for res := range c {
		switch v := res.(type) {
		case *naming.GlobReplyEntry:
			if v.Value.Name != "" {
				mapFunc(v.Value.Name)
			}
		case *naming.GlobReplyError:
			errors = append(errors, &v.Value)
		}
	}

	globErrors := make([]error, 0, len(errors))
	for _, err := range errors {
		globErrors = append(globErrors, fmt.Errorf("Glob error: %s: %v\n", err.Name, err.Error))
	}
	return nil, globErrors
}

func logGlobErrors(env *cmdline.Env, errors []error) {
	for _, err := range errors {
		vlog.Errorf("Glob error: %v", err)
	}
}

// getProfileNames uses glob to extract the list of profile names
// available from the binary server specified by endpoint.
func getProfileNames(ctx *context.T, env *cmdline.Env, endpoint string) ([]string, error) {
	profiles, err := profiles.GetKnownProfiles()
	if err != nil {
		return nil, err
	}

	pnames := make([]string, 0, len(profiles))
	for _, p := range profiles {
		pnames = append(pnames, p.Label)
	}
	return pnames, nil
}

func getNames(ctx *context.T, env *cmdline.Env, endpoint string) ([]string, error) {
	resultSet := make(map[string]struct{})
	err, errors := mapGlob(ctx, endpoint, func(s string) {
		resultSet[s] = struct{}{}
	})

	if err != nil {
		return nil, err
	}
	logGlobErrors(env, errors)
	s := set.String.ToSlice(resultSet)
	sort.Strings(s)
	return s, nil
}

func runBinaryTidy(ctx *context.T, env *cmdline.Env, args []string) error {
	if expected, got := 2, len(args); expected != got {
		return env.UsageErrorf("match: incorrect number of arguments, expected %d, got %d", expected, got)
	}

	appEndpoint, binEndpoint := args[0], args[1]

	profileNames, err := getProfileNames(ctx, env, binEndpoint)
	if err != nil {
		return err
	}

	envelopeNames, err := getNames(ctx, env, naming.Join(appEndpoint, "..."))
	if err != nil {
		return err
	}

	// Add every path in use to a set. Deletion scope is limited to
	// only the binEndpoint.
	bpaths := make(map[string]struct{})
	for _, en := range envelopeNames {
		// convert an envelope name into an envelope.
		ac := repository.ApplicationClient(en)

		for _, p := range profileNames {
			e, err := ac.Match(ctx, []string{p})
			if err != nil {
				// This error case is very noisy.
				vlog.VI(2).Infof("applicationd.Match(%s, %s) failed: %v\n", en, p, err)
				continue
			}

			root, relative := naming.SplitAddressName(e.Binary.File)
			if root == binEndpoint || root == "" {
				bpaths[relative] = struct{}{}
			}
			for _, sf := range e.Packages {
				root, relative := naming.SplitAddressName(sf.File)
				if root == binEndpoint || root == "" {
					bpaths[relative] = struct{}{}
				}
			}
		}
	}

	binaryNames, err := getNames(ctx, env, naming.Join(binEndpoint, "..."))
	if err != nil {
		return err
	}

	deletionCandidates := make([]int, 0, len(binaryNames)-len(envelopeNames))
	for i, bn := range binaryNames {
		_, relative := naming.SplitAddressName(bn)
		if _, ok := bpaths[relative]; ok {
			// relative is mentioned in an envelope.
			continue
		}

		if _, err := binarylib.Stat(ctx, bn); err != nil {
			// This name is not a binary.
			continue
		}
		deletionCandidates = append(deletionCandidates, i)
	}

	for _, i := range deletionCandidates {
		b := binaryNames[i]
		if err := binarylib.Delete(ctx, b); err != nil {
			vlog.Errorf("Couldn't delete binary %s: %v", b, err)
		}
	}

	return nil
}

var cmdApplicationTidy = &cmdline.Command{
	Runner: v23cmd.RunnerFunc(runApplicationTidy),
	Name:   "application",
	Short:  "Application sub-command tidies a specified applicationd",
	Long: `
Application sub-command uses the Tidy RPC to clean up outdated
envelopes from the specified appilcationd. Call this before tidying a
binaryd instance for maximum tidiness.
`,
	ArgsName: "<applicationd>",
	ArgsLong: `
<applicationd> is the name or endpoint of the applicationd instance
to tidy.
`,
}

func runApplicationTidy(ctx *context.T, env *cmdline.Env, args []string) error {
	vlog.Infof("runApplicationTidy")
	if expected, got := 1, len(args); expected != got {
		return env.UsageErrorf("match: incorrect number of arguments, expected %d, got %d", expected, got)
	}
	ac := repository.ApplicationClient(args[0])
	return ac.TidyNow(ctx)
}

var cmdRoot = &cmdline.Command{
	Name:  "tidy",
	Short: "Tidy binary repositories",
	Long: `
Tidy tidies the Vanadium repository by removing unused
envelopes and binaries.
`,
	Children: []*cmdline.Command{cmdBinaryTidy, cmdApplicationTidy},
}

func main() {
	cmdline.HideGlobalFlagsExcept()
	cmdline.Main(cmdRoot)
}
