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

// Chill changes the object class (ostensibly from a higher to lower one).
// See: https://cloud.google.com/storage/docs/storage-classes

package effects

// Change the storage class of an object in place.

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"os"

	cycler_pb "go.chromium.org/chromiumos/infra/proto/go/cycler"

	"cloud.google.com/go/storage"
)

func (ce ChillEffect) DefaultActor() interface{} {
	return objectChangeStorageClass
}

// ChillEffect runtime and configuration state.
type ChillEffect struct {
	Config *cycler_pb.ChillEffectConfiguration `json:"ChillEffectConfiguration"`
	// Real or mock actor, non-test invocations use util.objectChangeStorageClass
	actor func(ctx context.Context, client *storage.Client, srcAttr *storage.ObjectAttrs,
		toStorageClass cycler_pb.ChillEffectConfiguration_EnumStorageClass) error
}

// Init the chill effect.
func (ce *ChillEffect) Initialize(config interface{}, actor interface{}, checks ...bool) {
	orig, ok := config.(*cycler_pb.ChillEffectConfiguration)
	if !ok {
		log.Printf("Config could not be typecast: %+v", ok)
		os.Exit(2)
	}

	// Validate the configuration.
	if orig.ToStorageClass == cycler_pb.ChillEffectConfiguration_UNKNOWN {
		log.Printf("UNKNOWN is not a valid storage class.")
		os.Exit(2)
	}

	CheckMutationAllowed(checks)

	ce.Config = orig
	ce.actor = actor.(func(ctx context.Context, client *storage.Client, srcAttr *storage.ObjectAttrs,
		toStorageClass cycler_pb.ChillEffectConfiguration_EnumStorageClass) error)

}

// Enact does the move operation on the attr, _this deletes the old object_!
func (ce *ChillEffect) Enact(ctx context.Context, client *storage.Client, attr *storage.ObjectAttrs) (EffectResult, error) {
	err := ce.chillObject(ctx, client, attr)

	if err != nil {
		return nil, fmt.Errorf("Error chilling object (%v) in chillEffect.Enact: %v", attr.Name, err)
	}

	textResult := fmt.Sprintf("%+v", attr)
	jsonResult, err := json.Marshal(attr)

	if err != nil {
		return nil, fmt.Errorf("Error marshalling json in chillEffect.Enact: %v", err)
	}

	cr := ChillResult{
		acted:      true,
		jsonResult: string(jsonResult),
		textResult: textResult,
	}

	return &cr, nil
}

// Internal copy object command for google storage.
func (ce *ChillEffect) chillObject(ctx context.Context, client *storage.Client, attr *storage.ObjectAttrs) error {
	return ce.actor(ctx, client, attr, ce.Config.ToStorageClass)
}

// ChillResult defines all outputs of a move effect.
type ChillResult struct {
	acted      bool
	jsonResult string
	textResult string
}

// HasActed is true if the effect was applied.
func (cr ChillResult) HasActed() bool {
	return cr.acted
}

// JSONResult is the JSON result.
func (cr ChillResult) JSONResult() string {
	return cr.jsonResult
}

// TextResult is the unformatted text result.
func (cr ChillResult) TextResult() string {
	return cr.textResult
}
