// 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"
	"log"
	"time"

	"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)

// Resultstore Upload API message fields that are updated by the Logger.
const (
	startTimeField        = "timing.start_time"
	durationField         = "timing.duration"
	statusAttributesField = "status_attributes"
	filesField            = "files"
)

// 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.
	client, 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 := client.CreateInvocation(ctx, &resultstore.Invocation{
		ProjectID: projectID,
		ID:        uuid.New().String(),
		StartTime: time.Now(),
	})
	if err != nil {
		return nil, err
	}

	log.Printf("created invocation at: %s", environment.InvocationURL(invocation.ID))

	// Initialize the LoggerState.
	state := NewLoggerState()
	state.SetEnvironment(environment)
	state.SetAuthToken(authToken)
	state.SetInvocationID(invocation.ID)
	state.SetInvocationName(invocation.Name)

	return &logger{state: state, client: client}, nil
}

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

	return &logger{state: state, client: client}, nil
}

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

	// 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

	// SetInvocationStatus updates the status of the Invocation.
	SetInvocationStatus(context.Context, resultstore.Status) error

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

// The default Logger implementation
type logger struct {
	state  LoggerState
	client resultstore.UploadClient
}

// NewLogger is Visible for testing. Use `Start` and `Resume` instead.
func NewLogger(client resultstore.UploadClient, state LoggerState) Logger {
	return &logger{state: state, client: client}
}

func (l *logger) State() LoggerState {
	return l.state
}

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) SetInvocationStatus(ctx context.Context, status resultstore.Status) error {
	ctx, err := l.setAuthToken(ctx)
	if err != nil {
		return err
	}

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

	invocation := &resultstore.Invocation{
		Name:   invocationName,
		Status: status,
	}

	_, err = l.client.UpdateInvocation(ctx, invocation, []string{statusAttributesField})
	return err
}

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,
	}

	fieldsToUpdate := []string{
		startTimeField,
		durationField,
		statusAttributesField,
		filesField,
	}

	_, err = l.client.UpdateTestAction(ctx, action, fieldsToUpdate)
	return err
}

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),
	}

	fieldsToUpdate := []string{
		startTimeField,
		durationField,
		statusAttributesField,
	}

	_, err = l.client.UpdateConfiguredTarget(ctx, configuredTarget, fieldsToUpdate)
	return err
}

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.client.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.client.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),
		TestLogURI: e.LogFileURI,
	}

	fieldsToUpdate := []string{
		startTimeField,
		statusAttributesField,
	}

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

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.client.UpdateTarget(ctx, target, []string{startTimeField})
	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.EnvName,
		InvocationID: invocationID,
		Properties:   e.Properties,
	}

	_, err = l.client.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: &resultstore.TargetID{
			ID:           e.TestName,
			InvocationID: invocationID,
		},
		StartTime: dummyStartTime,
	}

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

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

	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{
		ID: &resultstore.ConfiguredTargetID{
			InvocationID: invocationID,
			ConfigID:     e.EnvName,
			TargetID:     e.TestName,
		},
		StartTime: e.StartTime,
	}

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

	if !l.state.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
	}

	// Use "test" as the action name because we have only one test action per target by
	// default, and "test" is meant to encompass everyting.
	action := &resultstore.TestAction{
		TestSuite: e.TestName,
		ID: &resultstore.TestActionID{
			ID:           "test",
			InvocationID: invocationID,
			TargetID:     e.TestName,
			ConfigID:     e.EnvName,
		},
		StartTime: e.StartTime,
	}

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

	if !l.state.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.state.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.client.FinishInvocation(ctx, invocationName)
}

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

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

func (l *logger) targetName(testName string) (string, error) {
	targetName := l.state.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.state.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.state.TestAction(testName, environmentName)
	if actionName == "" {
		return "", fmt.Errorf("no TestAction for test '%s' in environment '%s'", testName, environmentName)
	}
	return actionName, nil
}
