// Copyright 2021 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.

// FirmwareInstall state machine construction and helper

package firmwareservice

import (
	"chromiumos/test/provision/cmd/provisionserver/bootstrap/services"
	"context"
	"errors"
	"fmt"
	"path"

	conf "go.chromium.org/chromiumos/config/go"
	"go.chromium.org/chromiumos/config/go/test/api"
	"google.golang.org/grpc"
)

const FirmwarePathTmp = "/tmp/fw-provisioning-service/"

// FirmwareService inherits ServiceInterface
type FirmwareService struct {
	connection services.ServiceAdapterInterface

	mainRwPath *conf.StoragePath

	mainRoPath *conf.StoragePath
	ecRoPath   *conf.StoragePath
	pdRoPath   *conf.StoragePath
}

const CurlWithRetriesArgsFW = "-S -s -v -# -C - --retry 3 --retry-delay 60"

func NewFirmwareService(dutName string, dutClient api.DutServiceClient, wiringConn *grpc.ClientConn, req *api.InstallFirmwareRequest) (*FirmwareService, error) {
	fws, err := newConnectionlessFirmwareService(req)
	if err != nil {
		return nil, err
	}

	fws.connection = services.NewServiceAdapter(dutName, dutClient, wiringConn, false /*noReboot*/)
	if err := fws.connection.CreateDirectories(context.Background(), []string{FirmwarePathTmp}); err != nil {
		return nil, fmt.Errorf("failed to create folder %v: %w", FirmwarePathTmp, err)
	}

	return fws, nil
}

// NewFirmwareServiceFromExistingConnection is equivalent to the above constructor,
// but recycles a ServiceAdapter. Generally useful for tests.
func NewFirmwareServiceFromExistingConnection(connection services.ServiceAdapterInterface, req *api.InstallFirmwareRequest) (*FirmwareService, error) {
	fws, err := newConnectionlessFirmwareService(req)
	if err != nil {
		return nil, err
	}

	fws.connection = connection
	if err := fws.connection.CreateDirectories(context.Background(), []string{FirmwarePathTmp}); err != nil {
		return nil, fmt.Errorf("failed to create folder %v: %w", FirmwarePathTmp, err)
	}

	return fws, nil
}

// newConnectionlessFirmwareService is a contructor helper function that builds
// FirmwareService given a request, but leaves connection nil.
func newConnectionlessFirmwareService(req *api.InstallFirmwareRequest) (*FirmwareService, error) {
	if req.FirmwareConfig == nil {
		return nil, errors.New("request.FirmwareConfig is nil")
	}

	// Firmware may be updated in write-protected mode, where only 'rw' regions
	// would be update, or write-protection may be disabled (dangerous) in order
	// to update 'ro' regions.

	// The only 'rw' firmware is the main one, aka AP firmware.
	// Do it with write protection.
	mainRwPath := req.FirmwareConfig.MainRwPayload.GetFirmwareImagePath()

	// We may need to update 'ro' AP, EC, and PD(non-existent by now?) firmware.
	// Disable write protection.
	mainRoPath := req.FirmwareConfig.MainRoPayload.GetFirmwareImagePath()
	ecRoPath := req.FirmwareConfig.EcRoPayload.GetFirmwareImagePath()
	pdRoPath := req.FirmwareConfig.PdRoPayload.GetFirmwareImagePath()

	connection := services.ServiceAdapterInterface(nil)
	fws := FirmwareService{
		connection,
		mainRwPath,
		mainRoPath,
		ecRoPath,
		pdRoPath,
	}

	if !fws.UpdateRo() && !fws.UpdateRw() {
		return nil, errors.New("request.FirmwareConfig: no paths to images specified")
	}

	return &fws, nil
}

func (fws *FirmwareService) UpdateRw() bool {
	return fws.mainRwPath != nil
}
func (fws *FirmwareService) UpdateRo() bool {
	return (fws.mainRoPath != nil) || (fws.ecRoPath != nil) || (fws.pdRoPath != nil)
}

// GetFirstState returns the first state of this state machine
func (fws *FirmwareService) GetFirstState() services.ServiceState {
	if fws.UpdateRw() {
		return FirmwareUpdateRwState{
			service: *fws,
		}
	} else if fws.UpdateRo() {
		return FirmwareUpdateRoState{
			service: *fws,
		}
	}
	return nil
}

// CleanupOnFailure is called if one of service's states failes to Execute() and
// should clean up the temporary files, and undo the execution, if feasible.
func (fws *FirmwareService) CleanupOnFailure(states []services.ServiceState, executionErr error) error {
	// TODO(sfrolov): implement cleanup.
	return nil
}

// CopyImageToDUT copies the desired image to the DUT, passing through the caching layer.
func (fws *FirmwareService) CopyImageToDUT(ctx context.Context, remotePath *conf.StoragePath, localFilename string) error {
	if remotePath.HostType == conf.StoragePath_LOCAL || remotePath.HostType == conf.StoragePath_HOSTTYPE_UNSPECIFIED {
		return fmt.Errorf("only GS copying is implemented")
	}
	if err := fws.connection.CopyData(ctx, remotePath.GetPath(), fws.GetImagePath(localFilename)); err != nil {
		return fmt.Errorf("failed to cache %v: %w", remotePath.GetPath(), err)
	}

	return nil
}

// ExecuteWPFutility executes "futility" flashing utility with write protection.
// futility will be run with "--mode=autoupdate" and "--wp=1".
// futilityImageArg must include an argument to futility that provides a path
// to the AP image to be flashed.
func (fws FirmwareService) ExecuteWPFutility(ctx context.Context, futilityImageArg string) error {
	if len(futilityImageArg) == 0 {
		return fmt.Errorf("unable to flash: no futility Image args provided")
	}
	futilityArgs := []string{"update", "--mode=autoupdate", "--wp=1"}

	futilityArgs = append(futilityArgs, futilityImageArg)

	if _, err := fws.connection.RunCmd(ctx, "futility", futilityArgs); err != nil {
		return err
	}
	return nil
}

// ExecuteFutility executes "futility" flashing utility without write protection
// futility will be run with "--mode=recovery" and "--wp=0"
// futilityImageArgs must include argument(s) to futility that provide path(s)
// to the AP/EC/PD images to be flashed.
func (fws FirmwareService) ExecuteFutility(ctx context.Context, futilityImageArgs []string) error {
	if len(futilityImageArgs) == 0 {
		return fmt.Errorf("unable to flash: no futility Image args provided")
	}
	futilityArgs := []string{"update", "--mode=recovery", "--wp=0"}

	futilityArgs = append(futilityArgs, futilityImageArgs...)

	if _, err := fws.connection.RunCmd(ctx, "futility", futilityArgs); err != nil {
		return err
	}
	return nil
}

// GetImagePath returns joined path of directory with firmware and provided filename.
func (fws *FirmwareService) GetImagePath(filename string) string {
	return path.Join(FirmwarePathTmp, filename)
}
