package historycmd

import (
	"context"
	"flag"
	"time"

	"code.justin.tv/foundation/history-admin/clients/audit"
	"code.justin.tv/foundation/history.v2/historyin"
	"github.com/google/subcommands"
)

var (
	pst                   = time.FixedZone("America/Los_Angeles", -8)
	historyV2RolloverDate = time.Date(2018, time.April, 20, 9, 30, 0, 0, pst).UTC()
)

// SyncESCmd ...
type SyncESCmd struct {
	*BaseCmd
	poolSize int
}

// Name implements subcommands
func (cmd *SyncESCmd) Name() string {
	return "sync-es"
}

// Synopsis implements subcommands
func (cmd *SyncESCmd) Synopsis() string {
	return "sync an elasticsearch cluster with dynamodb"
}

// Usage implements subcommands
func (cmd *SyncESCmd) Usage() string {
	return `sync-es
`
}

// SetFlags implements subcommands
func (cmd *SyncESCmd) SetFlags(f *flag.FlagSet) {
	f.IntVar(&cmd.poolSize, "poolsize", 1, "number of goroutines to use to push to firehose")
}

// Execute implements subcommands
func (cmd *SyncESCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
	if err := cmd.execute(ctx); err != nil {
		cmd.Logger.Error(err)
		return subcommands.ExitFailure
	}
	return subcommands.ExitSuccess
}

func (cmd *SyncESCmd) execute(ctx context.Context) error {
	batchers := &batcherGroup{
		Batches: cmd.poolSize,
		History: cmd.HistoryIn(),
		Logger:  cmd.Logger,
	}
	batchers.Start()
	defer batchers.Wait()

	countExecutionScan := cmd.logExecutionCount("scanned", 10000)
	countExecutionSkip := cmd.logExecutionCount("skipped", 10000)
	countExecutionWrite := cmd.logExecutionCount("written", 10000)
	return cmd.Audit().ScanAuditsPooled(ctx, cmd.poolSize, func(a *audit.Audit) bool {
		countExecutionScan()

		if time.Time(a.CreatedAt).After(historyV2RolloverDate) {
			countExecutionSkip()
			return true
		}

		if err := batchers.Add(&historyin.Audit{
			UUID:         historyin.UUID(a.UUID),
			Action:       a.Action,
			UserType:     a.UserType,
			UserID:       a.UserID,
			ResourceType: a.ResourceType,
			ResourceID:   a.ResourceID,
			Description:  a.Description,
			CreatedAt:    historyin.Time(a.CreatedAt),
			TTL:          historyin.Duration(a.Expiry),
			Changes:      a.Changes,
		}); err != nil {
			cmd.Logger.Errorf("error adding to history: %s", err)
			return false
		}

		countExecutionWrite()
		return true
	})
}
