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

package tilo

import (
	"context"
	"errors"
	"fmt"
	"time"

	"fuchsia.googlesource.com/infra/infra/fuchsia/testexec"
	"fuchsia.googlesource.com/infra/infra/tilo/resultstore"
	"github.com/google/uuid"
)

// DummyStartTime is a placeholder start time to use when creating Targets.  ResultStore
// requires that a Target has some start time at creation, but Tilo supports creating and
// starting a test target as two separate actions, so start time is not relevant for
// Target creation.  This is used instead and is overwritten with the actual start time
// when a test is started.
var dummyStartTime = time.Date(2018, time.December, 30, 0, 0, 0, 0, time.UTC)

// Start creates a new Invocation in ResultStore and returns new Logger for modifying the
// Invocation. Host is the hostname of the ResultStore backend.
//
// TODO(IN-699): Define constants for the ResultStore backends and document them here.
func Start(ctx context.Context, environment resultstore.Environment, projectID string) (Logger, error) {
	// Connect to ResultStore.
	svc, err := resultstore.Connect(ctx, environment)
	if err != nil {
		return nil, err
	}

	// Create the Invocation.
	authToken := uuid.New().String()
	ctx, err = resultstore.SetAuthToken(ctx, authToken)
	if err != nil {
		return nil, err
	}

	invocation, err := svc.CreateInvocation(ctx, &resultstore.Invocation{
		ProjectID: projectID,
		ID:        uuid.New().String(),
		StartTime: time.Now(),
	})
	if err != nil {
		return nil, err
	}

	// Initialize the resultstore.Context.
	con := resultstore.NewContext()
	con.SetEnvironment(environment)
	con.SetAuthToken(authToken)
	con.SetInvocationID(invocation.ID)
	con.SetInvocationName(invocation.Name)

	return &logger{con: con, svc: svc}, nil
}

// Resume creates a new Logger for the Invocation identified by a resultstore.Context.
func Resume(ctx context.Context, con resultstore.Context) (Logger, error) {
	svc, err := resultstore.Connect(ctx, con.Environment())
	if err != nil {
		return nil, err
	}

	return &logger{con: con, svc: svc}, nil
}

// Logger is an interface for recording Fuchsia test events in ResultStore.
type Logger interface {
	// Context returns the context associated with the current invocation.  One Logger can
	// continue editing this Logger's Invocation by inheriting its Context.
	Context() resultstore.Context

	// LogEnvironment reports that a test Environment has been discovered.  The
	// environment is logged in ResultStore as a Configuration.
	LogEnvironment(context.Context, EnvironmentFoundEvent) error

	// LogTestFound reports that a test has been discovered.  The Test is logged in
	// ResultStore as a Target.
	LogTestFound(context.Context, TestFoundEvent) error

	// LogTestStarted reports that a test has started.  The corresponding ResultStore
	// target recieves a ConfiguredTarget and Action.
	LogTestStarted(context.Context, TestStartedEvent) error

	// LogTestFinished reports that a test has finished. The corresponding ResultStore
	// Action, ConfiguredTarget, and Target are updated and finished.
	LogTestFinished(context.Context, TestFinishedEvent) error

	// End finishes the Invocation.
	End(context.Context) error
}

// The default Logger implementation
type logger struct {
	con resultstore.Context
	svc resultstore.Service
}

// NewLogger is Visible for testing. Use `Start` and `Resume` instead.
func NewLogger(svc resultstore.Service, con resultstore.Context) Logger {
	return &logger{con: con, svc: svc}
}

func (l *logger) Context() resultstore.Context {
	return l.con
}

func (l *logger) LogEnvironment(ctx context.Context, e EnvironmentFoundEvent) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

	return l.createConfiguration(ctx, e)
}

func (l *logger) LogTestFound(ctx context.Context, e TestFoundEvent) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

	return l.createTarget(ctx, e)
}

func (l *logger) LogTestStarted(ctx context.Context, e TestStartedEvent) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

	if err := l.createConfiguredTarget(ctx, e); err != nil {
		return err
	}

	if err := l.createTestAction(ctx, e); err != nil {
		return err
	}

	return l.startTarget(ctx, e)
}

func (l *logger) LogTestFinished(ctx context.Context, e TestFinishedEvent) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

	if err := l.updateTestAction(ctx, e); err != nil {
		return err
	}

	if err := l.updateConfiguredTarget(ctx, e); err != nil {
		return err
	}

	if err := l.finishConfiguredTarget(ctx, e); err != nil {
		return err
	}

	if err := l.updateTarget(ctx, e); err != nil {
		return err
	}

	return l.finishTarget(ctx, e)
}

func (l *logger) End(ctx context.Context) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

	return l.finishInvocation(ctx)
}

func (l *logger) updateTestAction(ctx context.Context, e TestFinishedEvent) error {
	actionName, err := l.testAction(e.TestName, e.EnvName)
	if err != nil {
		return err
	}

	action := &resultstore.TestAction{
		Name:       actionName,
		StartTime:  e.StartTime,
		Duration:   e.EndTime.Sub(e.StartTime),
		Status:     resultstore.Status(e.TestStatus),
		TestLogURI: e.LogFileURI,
	}

	if _, err := l.svc.UpdateTestAction(ctx, action); err != nil {
		return err
	}

	return nil
}

func (l *logger) updateConfiguredTarget(ctx context.Context, e TestFinishedEvent) error {
	configuredTargetName, err := l.configuredTargetName(e.TestName, e.EnvName)
	if err != nil {
		return err
	}

	configuredTarget := &resultstore.ConfiguredTarget{
		Name:      configuredTargetName,
		StartTime: e.StartTime,
		Duration:  e.EndTime.Sub(e.StartTime),
		Status:    resultstore.Status(e.TestStatus),
	}

	if _, err := l.svc.UpdateConfiguredTarget(ctx, configuredTarget); err != nil {
		return err
	}

	return nil
}

func (l *logger) finishConfiguredTarget(ctx context.Context, e TestFinishedEvent) error {
	configuredTargetName, err := l.configuredTargetName(e.TestName, e.EnvName)
	if err != nil {
		return err
	}

	return l.svc.FinishConfiguredTarget(ctx, configuredTargetName)
}

func (l *logger) finishTarget(ctx context.Context, e TestFinishedEvent) error {
	targetName, err := l.targetName(e.TestName)
	if err != nil {
		return err
	}
	return l.svc.FinishTarget(ctx, targetName)
}

func (l *logger) updateTarget(ctx context.Context, e TestFinishedEvent) error {
	targetName, err := l.targetName(e.TestName)
	if err != nil {
		return err
	}

	target := &resultstore.Target{
		Name:      targetName,
		StartTime: e.StartTime,
		Duration:  e.EndTime.Sub(e.StartTime),
		Status:    resultstore.Status(e.TestStatus),
	}

	if _, err := l.svc.UpdateTarget(ctx, target); err != nil {
		return err
	}
	return nil
}

func (l *logger) startTarget(ctx context.Context, e TestStartedEvent) error {
	targetName, err := l.targetName(e.TestName)
	if err != nil {
		return err
	}

	target := &resultstore.Target{
		Name:      targetName,
		StartTime: e.StartTime,
	}

	_, err = l.svc.UpdateTarget(ctx, target)
	return err
}

func (l *logger) createConfiguration(ctx context.Context, e EnvironmentFoundEvent) error {
	invocationID, err := l.invocationID()
	if err != nil {
		return err
	}

	invocationName, err := l.invocationName()
	if err != nil {
		return err
	}

	config := &resultstore.Configuration{
		ID:           e.Name(),
		InvocationID: invocationID,
		Properties:   l.dimensionSetToMap(e.Dimensions),
	}

	_, err = l.svc.CreateConfiguration(ctx, config, invocationName)
	return err
}

func (l *logger) createTarget(ctx context.Context, e TestFoundEvent) error {
	invocationID, err := l.invocationID()
	if err != nil {
		return err
	}

	invocationName, err := l.invocationName()
	if err != nil {
		return err
	}

	target := &resultstore.Target{
		ID:           e.Name,
		InvocationID: invocationID,
		StartTime:    dummyStartTime,
	}

	target, err = l.svc.CreateTarget(ctx, target, invocationName)
	if err != nil {
		return err
	}

	if !l.con.SetTarget(e.Name, target.Name) {
		return fmt.Errorf("Target already exists for env %s", e.Name)
	}

	return nil
}

func (l *logger) createConfiguredTarget(ctx context.Context, e TestStartedEvent) error {
	invocationID, err := l.invocationID()
	if err != nil {
		return err
	}

	targetName, err := l.targetName(e.TestName)
	if err != nil {
		return err
	}

	configuredTarget := &resultstore.ConfiguredTarget{
		InvocationID: invocationID,
		ConfigID:     e.EnvName,
		TargetID:     e.TestName,
		StartTime:    e.StartTime,
	}

	configuredTarget, err = l.svc.CreateConfiguredTarget(ctx, configuredTarget, targetName)
	if err != nil {
		return err
	}

	if !l.con.SetConfiguredTarget(e.TestName, e.EnvName, configuredTarget.Name) {
		return fmt.Errorf("ConfiguredTarget already exists for env %s", e.EnvName)
	}

	return nil
}

func (l *logger) createTestAction(ctx context.Context, e TestStartedEvent) error {
	invocationID, err := l.invocationID()
	if err != nil {
		return err
	}

	configuredTargetName, err := l.configuredTargetName(e.TestName, e.EnvName)
	if err != nil {
		return err
	}

	action := &resultstore.TestAction{
		ID:           "test",
		InvocationID: invocationID,
		TestSuite:    e.TestName,
		TargetID:     e.TestName,
		ConfigID:     e.EnvName,
		StartTime:    e.StartTime,
	}

	action, err = l.svc.CreateTestAction(ctx, action, configuredTargetName)
	if err != nil {
		return err
	}

	if !l.con.SetTestAction(e.TestName, e.EnvName, action.Name) {
		return fmt.Errorf("Test Action already exists for test %s", e.TestName)
	}

	return nil
}

func (l *logger) setAuthToken(ctx context.Context) (context.Context, error) {
	token := l.con.AuthToken()
	if token == "" {
		return nil, errors.New("context is missing auth token")
	}

	ctx, err := resultstore.SetAuthToken(ctx, token)
	if err != nil {
		return nil, err
	}

	return ctx, nil
}

func (l *logger) finishInvocation(ctx context.Context) error {
	invocationName, err := l.invocationName()
	if err != nil {
		return err
	}

	return l.svc.FinishInvocation(ctx, invocationName)
}

func (l *logger) invocationID() (string, error) {
	invocationID := l.con.InvocationID()
	if invocationID == "" {
		return "", errors.New("context is missing invocation id")
	}
	return invocationID, nil
}

func (l *logger) invocationName() (string, error) {
	invocationName := l.con.InvocationName()
	if invocationName == "" {
		return "", errors.New("context is missing invocation name")
	}
	return invocationName, nil
}

func (l *logger) targetName(testName string) (string, error) {
	targetName := l.con.Target(testName)
	if targetName == "" {
		return "", fmt.Errorf("no target for test '%s'", testName)
	}
	return targetName, nil
}

func (l *logger) configuredTargetName(testName, environmentName string) (string, error) {
	configuredTargetName := l.con.ConfiguredTarget(testName, environmentName)
	if configuredTargetName == "" {
		return "", fmt.Errorf("no ConfiguredTarget for test '%s' in environment '%s'", testName, environmentName)
	}
	return configuredTargetName, nil
}

func (l *logger) testAction(testName, environmentName string) (string, error) {
	actionName := l.con.TestAction(testName, environmentName)
	if actionName == "" {
		return "", fmt.Errorf("no TestAction for test '%s' in environment '%s'", testName, environmentName)
	}
	return actionName, nil
}

func (l *logger) dimensionSetToMap(set testexec.DimensionSet) map[string]string {
	return map[string]string{
		"device_type": set.DeviceType,
	}
}
