package cli

import (
	"context"
	"time"

	"github.com/pkg/errors"

	"github.com/kopia/kopia/internal/clock"
	"github.com/kopia/kopia/repo"
	"github.com/kopia/kopia/repo/maintenance"
)

var maintenanceInfoCommand = maintenanceCommands.Command("info", "Display maintenance information").Alias("status")

func runMaintenanceInfoCommand(ctx context.Context, rep repo.DirectRepository) error {
	p, err := maintenance.GetParams(ctx, rep)
	if err != nil {
		return errors.Wrap(err, "unable to get maintenance params")
	}

	s, err := maintenance.GetSchedule(ctx, rep)
	if err != nil {
		return errors.Wrap(err, "unable to get maintenance schedule")
	}

	if jsonOutput {
		printStdout("%s\n", jsonBytes(s))
		return nil
	}

	printStdout("Owner: %v\n", p.Owner)
	printStdout("Quick Cycle:\n")
	displayCycleInfo(&p.QuickCycle, s.NextQuickMaintenanceTime, rep)

	printStdout("Full Cycle:\n")
	displayCycleInfo(&p.FullCycle, s.NextFullMaintenanceTime, rep)

	printStdout("Recent Maintenance Runs:\n")

	for run, timings := range s.Runs {
		printStdout("  %v:\n", run)

		for _, t := range timings {
			errInfo := ""
			if t.Success {
				errInfo = "SUCCESS"
			} else {
				errInfo = "ERROR: " + t.Error
			}

			printStdout(
				"    %v (%v) %v\n",
				formatTimestamp(t.Start),
				t.End.Sub(t.Start).Truncate(time.Second),
				errInfo)
		}
	}

	return nil
}

func displayCycleInfo(c *maintenance.CycleParams, t time.Time, rep repo.DirectRepository) {
	printStdout("  scheduled: %v\n", c.Enabled)

	if c.Enabled {
		printStdout("  interval: %v\n", c.Interval)

		if rep.Time().Before(t) {
			printStdout("  next run: %v (in %v)\n", formatTimestamp(t), clock.Until(t).Truncate(time.Second))
		} else {
			printStdout("  next run: now\n")
		}
	}
}

func init() {
	registerJSONOutputFlags(maintenanceInfoCommand)
	maintenanceInfoCommand.Action(directRepositoryReadAction(runMaintenanceInfoCommand))
}
