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

// AshInstall state machine construction and helper

package ashservice

import (
	"chromiumos/test/provision/cmd/provisionserver/bootstrap/services"
	"context"
	"fmt"
	"log"
	"path/filepath"
	"time"

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

// File specific consts
const (
	autotestDir      = "/usr/local/autotest/deps/chrome_test/test_src/out/Release/"
	stagingDirectory = "/tmp/_provisioning_service_chrome_deploy"
	targetDir        = "/opt/google/chrome"
	tastDir          = "/usr/local/libexec/chrome-binary-tests/"
)

// Time specific consts
const (
	twoSeconds = 2 * time.Second
	tenSeconds = 10 * time.Second
)

// binaries to be copied in installation
var copyPaths = [...]string{
	"ash_shell",
	"aura_demo",
	"chrome",
	"chrome-wrapper",
	"chrome.pak",
	"chrome_100_percent.pak",
	"chrome_200_percent.pak",
	"content_shell",
	"content_shell.pak",
	"extensions/",
	"lib/*.so",
	"libffmpegsumo.so",
	"libpdf.so",
	"libppGoogleNaClPluginChrome.so",
	"libosmesa.so",
	"libwidevinecdmadapter.so",
	"libwidevinecdm.so",
	"locales/",
	"nacl_helper_bootstrap",
	"nacl_irt_*.nexe",
	"nacl_helper",
	"resources/",
	"resources.pak",
	"xdg-settings",
	"*.png",
}

// test binaries to be copied in installation
var testPaths = [...]string{
	"*test",
	"*tests",
}

// AshService inherits ServiceInterface
type AshService struct {
	connection services.ServiceAdapterInterface
	imagePath  *conf.StoragePath
}

func NewAshService(dutName string, dutClient api.DutServiceClient, wiringConn *grpc.ClientConn, req *api.InstallAshRequest) AshService {
	service := AshService{
		connection: services.NewServiceAdapter(dutName, dutClient, wiringConn, false /*noRebot*/),
		imagePath:  req.AshImagePath,
	}

	return service
}

// NewAshServiceFromExistingConnection is equivalent to the above constructor,
// but recycles a ServiceAdapter. Generally useful for tests.
func NewAshServiceFromExistingConnection(conn services.ServiceAdapterInterface, imagePath *conf.StoragePath) AshService {
	return AshService{
		connection: conn,
		imagePath:  imagePath,
	}
}

// GetFirstState returns the first state of this state machine
func (a *AshService) GetFirstState() services.ServiceState {
	return AshPrepareState{
		service: *a,
	}
}

// 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 (a *AshService) CleanupOnFailure(states []services.ServiceState, executionErr error) error {
	// TODO: evaluate whether cleanup is needed.
	return nil
}

// CleanUpStagingDirectory simply deletes the staging directory
func (a *AshService) CleanUpStagingDirectory(ctx context.Context) error {
	return a.connection.DeleteDirectory(ctx, stagingDirectory)
}

// CreateStagingDirectory ensures a clean staging directory is present
func (a AshService) CreateStagingDirectory(ctx context.Context) error {
	if err := a.CleanUpStagingDirectory(ctx); err != nil {
		return err
	}

	return a.connection.CreateDirectories(ctx, []string{stagingDirectory})
}

// CreateBinaryDirectories creates all directories which will house the binaries for the install
func (a *AshService) CreateBinaryDirectories(ctx context.Context) error {
	return a.connection.CreateDirectories(ctx, []string{targetDir, autotestDir, tastDir})
}

// CopyImageToDUT copies the desired image to the DUT, passing through the caching layer.
func (a *AshService) CopyImageToDUT(ctx context.Context) error {
	if a.imagePath.HostType == conf.StoragePath_LOCAL || a.imagePath.HostType == conf.StoragePath_HOSTTYPE_UNSPECIFIED {
		return fmt.Errorf("only GS copying is implemented")
	}
	err := a.connection.PipeData(ctx, a.imagePath.GetPath(), fmt.Sprintf("tar --ignore-command-error --overwrite --preserve-permissions --directory=%s -xf -", stagingDirectory))
	if err != nil {
		return fmt.Errorf("failed to download and uncompress ash compressed, %w", err)
	}

	return nil
}

// MountRootFS mounts the root filesystem as a read/write
func (a *AshService) MountRootFS(ctx context.Context) error {
	if _, err := a.connection.RunCmd(ctx, "mount", []string{"-o", "remount,rw", "/"}); err != nil {
		return fmt.Errorf("could not mount root file system, %w", err)
	}
	return nil
}

// isChromeInUse determines if chrome is currently running
func (a *AshService) isChromeInUse(ctx context.Context) bool {
	_, err := a.connection.RunCmd(ctx, "lsof", []string{fmt.Sprintf("%s/chrome", targetDir)})
	return err != nil
}

// StopChrome stops the UI
func (a *AshService) StopChrome(ctx context.Context) error {
	if _, err := a.connection.RunCmd(ctx, "stop", []string{"ui"}); err != nil {
		// stop ui returns error when UI is terminated, so ignore error here
		log.Printf("failed to stop chrome, %s", err)
	}
	return nil
}

// KillChrome tries to pkill chrome, retrying/re-polling every two seconds
func (a *AshService) KillChrome(ctx context.Context) error {
	for start := time.Now(); time.Since(start) < tenSeconds; time.Sleep(twoSeconds) {
		if !a.isChromeInUse(ctx) {
			return nil
		}
		log.Printf("chrome binary is still running, killing...")
		if _, err := a.connection.RunCmd(ctx, "pkill", []string{"'chrome|session_manager'"}); err != nil {
			return fmt.Errorf("failed run pkill, %s", err)
		}
	}
	return fmt.Errorf("failed to kill chrome")
}

// Deploy rsyncs files relevant to the install to the correct bin locations
func (a *AshService) Deploy(ctx context.Context) error {
	for _, file := range copyPaths {
		if err := a.deployFile(ctx, file, targetDir); err != nil {
			return fmt.Errorf("could not deploy copy file, %w", err)
		}
	}
	for _, file := range testPaths {
		if err := a.deployFile(ctx, file, autotestDir); err != nil {
			return fmt.Errorf("could not deploy autotest file, %w", err)
		}
		if err := a.deployFile(ctx, file, tastDir); err != nil {
			return fmt.Errorf("could not deploy tast file, %w", err)
		}
	}
	return nil
}

// deployFile rsyncs one specific file to the desired bin dir
func (a *AshService) deployFile(ctx context.Context, file string, destination string) error {
	source := fmt.Sprintf("%s/%s", stagingDirectory, file)
	target := filepath.Dir(fmt.Sprintf("%s/%s", destination, file))

	if exists, err := a.connection.PathExists(ctx, source); err != nil {
		return fmt.Errorf("failed to determine file existance, %s", err)
	} else if !exists {
		return nil
	}

	if _, err := a.connection.RunCmd(ctx, "rsync", []string{"-av", source, target}); err != nil {
		return fmt.Errorf("failed run rsync, %s", err)
	}
	return nil
}

// ReloadBus kill the bus daemon with a SIGHUP
func (a *AshService) ReloadBus(ctx context.Context) error {
	if _, err := a.connection.RunCmd(ctx, "killall", []string{"-HUP", "dbus-daemon"}); err != nil {
		return fmt.Errorf("failed to reload dbus, %s", err)
	}
	return nil
}

// StartChrome restarts the ui
func (a *AshService) StartChrome(ctx context.Context) error {
	if _, err := a.connection.RunCmd(ctx, "start", []string{"ui"}); err != nil {
		return fmt.Errorf("failed to start ui, %s", err)
	}
	return nil
}
