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

import (
	"context"
	"errors"
	"fmt"
	"io"
	"log"
	"strconv"
	"time"

	"go.fuchsia.dev/fuchsia/tools/net/sshutil"
	"golang.org/x/crypto/ssh"
)

// TODO(IN-977) Clean this up per suggestions in go/fxr/251550

const (
	// Controller machines use 192.168.42.1/24 for swarming bots
	// This will broadcast to that entire subnet.
	botBroadcastAddr = "192.168.42.255:9"

	// Controller machines have multiple interfaces, currently
	// 'eno2' is used for swarming bots.
	botInterface = "eno2"

	// Duration to wait before sending dm reboot-recovery after powercycle
	powercycleWait = 1 * time.Minute
)

// PowerClient represents a power management configuration for a particular device.
type PowerClient struct {
	// Type is the type of manager to use.
	Type string `json:"type"`

	// Host is the network hostname of the manager
	Host string `json:"host"`

	// Username is the username used to log in to the manager.
	Username string `json:"username"`

	// Password is the password used to log in to the manager..
	Password string `json:"password"`

	// PDUIp is the IP address of the pdu
	PDUIp string `json:"pduIp"`

	// PDUPort is the port the PDU uses to connect to this device.
	PDUPort string `json:"pduPort"`
}

type Rebooter interface {
	reboot() error
}

type SshRebooter struct {
	nodename string
	signers  []ssh.Signer
}

type SerialRebooter struct {
	serial io.ReadWriter
}

// RebootDevice attempts to reboot the specified device into recovery, and
// additionally uses the given configuration to reboot the device if specified.
func (c PowerClient) RebootDevice(signers []ssh.Signer, nodename string, serial io.ReadWriter) error {
	var rebooter Rebooter
	log.Printf("Attempting to soft reboot device %s", nodename)
	if serial == nil {
		log.Printf("Using SSH to reboot.")
		rebooter = NewSSHRebooter(nodename, signers)
	} else {
		log.Printf("Using serial to reboot.")
		rebooter = NewSerialRebooter(serial)
	}
	return rebooter.reboot()
}

// Powercycle the device using an out of band method
func (c PowerClient) Powercycle(nodename string, mac string, serial io.ReadWriter) error {
	log.Printf("Attempting to powercycle device %s", nodename)
	switch c.Type {
	case "AMT":
		log.Printf("Using AMT to powercycle.")
		return AMTReboot(c.Host, c.Username, c.Password)
	case "WOL":
		if serial == nil {
			return errors.New(fmt.Sprintf("WOL Reboot requires serial connection."))
		}
		log.Printf("Using WOL to powercycle")
		if err := WOLReboot(botBroadcastAddr, botInterface, mac); err != nil {
			return err
		}
	case "PDU":
		if serial == nil {
			return errors.New(fmt.Sprintf("PDU Reboot requires serial connection."))
		}
		log.Printf("Using PDU to powercycle")
		port, err := strconv.Atoi(c.PDUPort)
		if err != nil {
			return err
		}
		if err := PDUReboot(port, c.PDUIp, c.Username, c.Password); err != nil {
			return err
		}
	default:
		return errors.New(fmt.Sprintf("%v does not have AMT, WOL, or PDU support. Cannot powercycle.", nodename))
	}
	// Send dm reboot-recovery to the device so that it always boots into zedboot.
	log.Printf("Powercycle complete; using serial to send dm reboot recovery.")
	time.Sleep(powercycleWait)
	rebooter := NewSerialRebooter(serial)
	return rebooter.reboot()
}

func NewSerialRebooter(serial io.ReadWriter) *SerialRebooter {
	return &SerialRebooter{
		serial: serial,
	}
}

func (s *SerialRebooter) reboot() error {
	_, err := io.WriteString(s.serial, "\ndm reboot-recovery\n")
	return err
}

func NewSSHRebooter(nodename string, signers []ssh.Signer) *SshRebooter {
	return &SshRebooter{
		nodename: nodename,
		signers:  signers,
	}
}

func (s *SshRebooter) reboot() error {
	config, err := sshutil.DefaultSSHConfigFromSigners(s.signers...)
	if err != nil {
		return err
	}

	client, err := sshutil.ConnectToNode(context.Background(), s.nodename, config)
	if err != nil {
		return err
	}

	defer client.Close()

	session, err := client.NewSession()
	if err != nil {
		return err
	}

	defer session.Close()

	// Invoke `dm reboot-recovery`
	err = session.Start("dm reboot-recovery")
	if err != nil {
		return err
	}

	done := make(chan error)
	go func() {
		done <- session.Wait()
	}()

	select {
	case err := <-done:
		return err
	case <-time.After(10*time.Second):
		return nil
	}
}
