// 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 $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go . -help

package main

import (
	"fmt"
	"io"
	"os"
	"os/user"
	"path/filepath"
	"regexp"
	"time"

	"v.io/x/lib/cmdline"
)

var (
	flagCutoff   time.Duration
	flagProgname string
	flagVerbose  bool
	flagDryrun   bool

	cmdGCLogs = &cmdline.Command{
		Runner: cmdline.RunnerFunc(garbageCollectLogs),
		Name:   "gclogs",
		Short:  "safely deletes old log files",
		Long: `
Command gclogs safely deletes old log files.

It looks for file names that match the format of files produced by the vlog
package, and deletes the ones that have not changed in the amount of time
specified by the --cutoff flag.

Only files produced by the same user as the one running the gclogs command
are considered for deletion.
`,
		ArgsName: "<dir> ...",
		ArgsLong: "<dir> ... A list of directories where to look for log files.",
	}
)

func init() {
	cmdGCLogs.Flags.DurationVar(&flagCutoff, "cutoff", 24*time.Hour, "The age cut-off for a log file to be considered for garbage collection.")
	cmdGCLogs.Flags.StringVar(&flagProgname, "program", ".*", `A regular expression to apply to the program part of the log file name, e.g ".*test".`)
	cmdGCLogs.Flags.BoolVar(&flagVerbose, "verbose", false, "If true, each deleted file is shown on stdout.")
	cmdGCLogs.Flags.BoolVar(&flagDryrun, "n", false, "If true, log files that would be deleted are shown on stdout, but not actually deleted.")
}

func main() {
	cmdline.Main(cmdGCLogs)
}

func garbageCollectLogs(env *cmdline.Env, args []string) error {
	if len(args) == 0 {
		env.UsageErrorf("gclogs requires at least one argument")
	}
	timeCutoff := time.Now().Add(-flagCutoff)
	currentUser, err := user.Current()
	if err != nil {
		return err
	}
	programRE, err := regexp.Compile(flagProgname)
	if err != nil {
		return err
	}
	var lastErr error
	for _, logdir := range args {
		if err := processDirectory(env, logdir, timeCutoff, programRE, currentUser.Username); err != nil {
			lastErr = err
		}
	}
	return lastErr
}

func processDirectory(env *cmdline.Env, logdir string, timeCutoff time.Time, programRE *regexp.Regexp, username string) error {
	fmt.Fprintf(env.Stdout, "Processing: %q\n", logdir)

	f, err := os.Open(logdir)
	if err != nil {
		return err
	}
	defer f.Close()

	var lastErr error
	deleted := 0
	symlinks := []string{}
	for {
		fi, err := f.Readdir(100)
		if err == io.EOF {
			break
		}
		if err != nil {
			lastErr = err
			break
		}
		for _, file := range fi {
			fullname := filepath.Join(logdir, file.Name())
			if file.IsDir() {
				if flagVerbose {
					fmt.Fprintf(env.Stdout, "Skipped directory: %q\n", fullname)
				}
				continue
			}
			lf, err := parseFileInfo(logdir, file)
			if err != nil {
				if flagVerbose {
					fmt.Fprintf(env.Stdout, "Not a log file: %q\n", fullname)
				}
				continue
			}
			if lf.user != username {
				if flagVerbose {
					fmt.Fprintf(env.Stdout, "Skipped log file created by other user: %q\n", fullname)
				}
				continue
			}
			if !programRE.MatchString(lf.program) {
				if flagVerbose {
					fmt.Fprintf(env.Stdout, "Skipped log file doesn't match %q: %q\n", flagProgname, fullname)
				}
				continue
			}
			if lf.symlink {
				symlinks = append(symlinks, fullname)
				continue
			}
			if file.ModTime().Before(timeCutoff) {
				if flagDryrun {
					fmt.Fprintf(env.Stdout, "Would delete %q\n", fullname)
					continue
				}
				if flagVerbose {
					fmt.Fprintf(env.Stdout, "Deleting %q\n", fullname)
				}
				if err := os.Remove(fullname); err != nil {
					lastErr = err
				} else {
					deleted++
				}
			}
		}
	}
	// Delete broken links.
	for _, sl := range symlinks {
		if _, err := os.Stat(sl); err != nil && os.IsNotExist(err) {
			if flagDryrun {
				fmt.Fprintf(env.Stdout, "Would delete symlink %q\n", sl)
				continue
			}
			if flagVerbose {
				fmt.Fprintf(env.Stdout, "Deleting symlink %q\n", sl)
			}
			if err := os.Remove(sl); err != nil {
				lastErr = err
			} else {
				deleted++
			}
		}

	}
	fmt.Fprintf(env.Stdout, "Number of files deleted: %d\n", deleted)
	return lastErr
}
