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

package dut

import (
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

	"github.com/google/syz-repro-automation/cmd"
)

const (
	dutSleep    = 2 * time.Second
	flashBuffer = 20 * time.Minute
)

type leasedDut struct {
	hostname string
	model    string
	imageID  string
	expTime  time.Time
}

var currDut *leasedDut

// Get leases a DUT if the current DUT is nil, the model requested for the DUT has changed, or the DUT lease is about to expire.
// Otherwise if only the DUT imageID has changed, we will get the new image.
// If all fields are the same, Get does nothing.
// Returns the current DUT's hostname.
func Get(model, imageID string, minutes int, timeNeeded time.Duration) (string, error) {
	if currDut == nil || currDut.model != model || time.Now().Add(timeNeeded).Add(flashBuffer).After(currDut.expTime) {
		Abandon()
		hostname, err := lease(model, minutes)
		if err != nil {
			return "", err
		}
		WaitForDut(hostname)
		expTime := time.Now().Add(time.Duration(minutes) * time.Minute)
		if err := getKernel(hostname, imageID); err != nil {
			abandonDut(hostname)
			return "", err
		}
		// Note imageID may not correspond to the actual image on the DUT.
		// If user given imageID does not work and second-latest image is flashed onto DUT,
		// imageID will still equal user given imageID. This way if user given imageID is present again,
		// we will not try to flash the user given imageID again, and instead use the current DUT.
		currDut = &leasedDut{
			hostname: hostname,
			model:    model,
			imageID:  imageID,
			expTime:  expTime,
		}
		return currDut.hostname, nil
	} else if currDut.imageID != imageID {
		if err := getKernel(currDut.hostname, imageID); err != nil {
			Abandon()
			return "", err
		}
		currDut.imageID = imageID
	}
	return currDut.hostname, nil
}

// lease leases a DUT of type model and for specified minutes, runs crosfleet dut lease.
// Returns leased DUT's hostname.
func lease(model string, minutes int) (string, error) {
	log.Printf("Leasing model %v device for %v minutes...\n", model, minutes)
	ret, err := cmd.RunCmd(true, "crosfleet", "dut", "lease", "-model", model, "--minutes", strconv.Itoa(minutes))
	if err != nil {
		return "", fmt.Errorf("error leasing device: %v", err)
	}

	// Prints out lease information for user.
	log.Println(ret)

	// ret looks like "Leased chromeos6-row18-rack16-host10 until 19 Jul 21 19:58 UTC".
	// Returns hostname, e.g. chromeos6-row18-rack16-host10.
	return strings.Split(ret, " ")[1] + ".cros", nil
}

func getKernel(hostname, imageID string) error {
	if err := flashKernel(hostname, imageID); err != nil {
		if imageID == "" {
			return fmt.Errorf("error flashing latest kernel: %v", err)
		}
		log.Printf("Flashing image %v failed: %v.\nTrying to flash latest image.", imageID, err)
		if err := flashKernel(hostname, ""); err != nil {
			return fmt.Errorf("error flashing latest kernel: %v", err)
		}
	}
	return nil
}

// flashKernel flashes a kernel onto the DUT at hostname, runs cros flash.
func flashKernel(hostname, imageID string) error {
	board, err := getBoard(hostname)
	if err != nil {
		return fmt.Errorf("unable to get board for DUT: %v", err)
	}
	if imageID == "" {
		log.Printf("Image id not provided, fetching second-latest image for board %v...\n", board)
		imageID, err = getSecondLatestImage(board)
		if err != nil {
			return fmt.Errorf("unable to get latest image for board: %v", err)
		}
	}
	log.Printf("Flashing kernel onto DUT...")
	ssh := "ssh://root@" + hostname
	xBuddy := "xBuddy://remote/" + board + "-debug-kernel-postsubmit/" + imageID
	if _, err = cmd.RunCmd(true, "cros", "flash", "--no-ping", "--board="+board, ssh, xBuddy); err != nil {
		return fmt.Errorf("error flashing kernel onto DUT: %v", err)
	}
	log.Printf("Finished flashing kernel onto DUT")

	return nil
}

// WaitForDut checks if the DUT is up.
func WaitForDut(hostname string) {
	log.Println("Pinging DUT at " + hostname + "...")
	args := []string{
		"ssh",
		"-o", "UserKnownHostsFile=/dev/null",
		"-o", "BatchMode=yes",
		"-o", "IdentitiesOnly=yes",
		"-o", "StrictHostKeyChecking=no",
		"-o", "ConnectTimeout=10",
		"root@" + hostname, "pwd",
	}
	for {
		if _, err := cmd.RunCmd(false, args...); err != nil {
			log.Printf("ssh failed: %v. sleeping for %v and trying again.", err, dutSleep)
			time.Sleep(dutSleep)
		} else {
			break
		}
	}
}

func abandonDut(hostname string) {
	log.Println("Abandoning DUT at " + hostname + "...")
	ret, err := cmd.RunCmd(false, "crosfleet", "dut", "abandon", hostname)
	if err != nil {
		log.Fatal(fmt.Errorf("error abandoning DUT: %v", err))
	}
	log.Println(ret)
}

// Abandon abandons the DUT at hostname, runs crosfleet dut abandon.
func Abandon() {
	if currDut == nil {
		return
	}
	abandonDut(currDut.hostname)
	currDut = nil
}

func getSecondLatestImage(board string) (string, error) {
	bucket := "gs://chromeos-image-archive/" + board + "-debug-kernel-postsubmit"
	ret, err := cmd.RunCmd(false, "gsutil.py", "ls", bucket)
	if err != nil {
		return "", err
	}
	lines := strings.Split(ret, "\n")

	// Get third to last line as the last line is blank.
	// We get the second latest image because flashing the latest image runs into issues.
	imageLine := lines[len(lines)-3]

	// imageLine looks like gs://chromeos-image-archive/octopus-debug-kernel-postsubmit/R94-14102.0.0-51496-8841198623588369056/.
	sections := strings.Split(imageLine, "/")

	// Get second to last line as the last line is blank.
	latestImage := sections[len(sections)-2]
	log.Printf("Found latest image %v for board %v\n", latestImage, board)
	return latestImage, nil
}

func getBoard(hostname string) (string, error) {
	ret, err := cmd.RunCmd(false, "crosfleet", "dut", "info", hostname)
	if err != nil {
		return "", fmt.Errorf("error getting dut info: %v", err)
	}

	/* ret looks like:
	DUT_HOSTNAME=chromeos6-row18-rack16-host4.cros
	MODEL=garg
	BOARD=octopus
	SERVO_HOSTNAME=chromeos6-row17-rack16-labstation1
	SERVO_PORT=9985
	SERVO_SERIAL=G1911051544 */
	lines := strings.Split(ret, "\n")
	return strings.Split(lines[2], "=")[1], nil
}
