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

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	"github.com/google/uuid"
	"go.fuchsia.dev/fuchsia/tools/net/digest"
)

const (
	// https://software.intel.com/en-us/node/645995
	PowerStateOn             = 2
	PowerStateLightSleep     = 3
	PowerStateDeepSleep      = 4
	PowerStatePowerCycleSoft = 5
	PowerStateOffHard        = 6
	PowerStateHibernate      = 7
	PowerStateOffSoft        = 8
	PowerStatePowerCycleHard = 9
	PowerStateMasterBusReset = 10
)

// Printf string with placeholders for destination uri, message uuid
const payloadTmpl = `
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:pms="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PowerManagementService">
<s:Header>
  <wsa:Action s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PowerManagementService/RequestPowerStateChange</wsa:Action>
  <wsa:To s:mustUnderstand="true">%s</wsa:To>
  <wsman:ResourceURI s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PowerManagementService</wsman:ResourceURI>
  <wsa:MessageID s:mustUnderstand="true">uuid:%s</wsa:MessageID>
  <wsa:ReplyTo><wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address></wsa:ReplyTo>
  <wsman:SelectorSet>
    <wsman:Selector Name="Name">Intel(r) AMT Power Management Service</wsman:Selector>
    <wsman:Selector Name="SystemName">Intel(r) AMT</wsman:Selector>
    <wsman:Selector Name="CreationClassName">CIM_PowerManagementService</wsman:Selector>
    <wsman:Selector Name="SystemCreationClassName">CIM_ComputerSystem</wsman:Selector>
  </wsman:SelectorSet>
</s:Header>
<s:Body>
  <pms:RequestPowerStateChange_INPUT>
    <pms:PowerState>%d</pms:PowerState>
    <pms:ManagedElement>
      <wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
      <wsa:ReferenceParameters>
        <wsman:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</wsman:ResourceURI>
        <wsman:SelectorSet>
          <wsman:Selector Name="Name">ManagedSystem</wsman:Selector>
          <wsman:Selector Name="CreationClassName">CIM_ComputerSystem</wsman:Selector>
        </wsman:SelectorSet>
      </wsa:ReferenceParameters>
    </pms:ManagedElement>
  </pms:RequestPowerStateChange_INPUT>
</s:Body>
</s:Envelope>
`

// Reboot sends a Master Bus Reset to an AMT compatible device at host:port.
func AMTReboot(host, username, password string) error {
	// AMT over http always uses port 16992
	uri, err := url.Parse(fmt.Sprintf("http://%s:16992/wsman", host))
	if err != nil {
		return err
	}
	// Generate MessageID
	uuid := uuid.New()
	payload := fmt.Sprintf(payloadTmpl, uri.String(), uuid, PowerStatePowerCycleSoft)

	t := digest.NewTransport(username, password)
	req, err := http.NewRequest("POST", uri.String(), strings.NewReader(payload))
	if err != nil {
		return err
	}
	res, err := t.RoundTrip(req)
	if err != nil {
		return err
	}
	defer res.Body.Close()

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return err
	}
	returnValue := string(strings.Split(string(body), "ReturnValue>")[1][0])
	if returnValue != "0" {
		return fmt.Errorf("amt reboot ReturnValue=%s", returnValue)
	}

	return nil
}

type AMTPowerManager struct {
	host string
	user string
	pwd  string
}

func NewAMTPowerManager(host string, user string, pwd string) *AMTPowerManager {
	return &AMTPowerManager{
		host: host,
		user: user,
		pwd:  pwd,
	}
}

func (a *AMTPowerManager) Powercycle() error {
	return AMTReboot(a.host, a.user, a.pwd)
}
