// Copyright 2019 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 (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

// PDUConn encapsultes PDU connection settings.
type PDUConn struct {
	// Client is the client used to perform all requests.
	Client *http.Client

	// Host is the network hostname of the PDU.
	Host string

	// Username is the username by which we can log in to the PDU.
	Username string

	// Password is the password by which we can log in to the PDU.
	Password string

	// token is the authentication token obtained by Login.
	token string
}

type message struct {
	ID    int             `json:"msgid,omitempty"`
	Reply string          `json:"reply,omitempty"`
	Data  json.RawMessage `json:"data,omitempty"`
	Error struct {
		Name    string `json:"name"`
		Message string `json:"message"`
		Status  int    `json:"status"`
	} `json:"error,omitempty"`
}

// NewPDUConn initializes and returns a new PDUConn struct.
func NewPDUConn(host string, uname string, pwd string) *PDUConn {
	return &PDUConn{
		Client: &http.Client{
			Transport: &http.Transport{
				TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
			},
		},
		Host:     host,
		Username: uname,
		Password: pwd,
	}
}

// Login performs a login and obtains authorization token used for other calls.
func (c *PDUConn) Login() error {
	q := make(url.Values)
	q.Set("username", c.Username)
	q.Set("password", c.Password)

	u := url.URL{
		Scheme:   "https",
		Host:     c.Host,
		Path:     "/api/AuthenticationControllers/login",
		RawQuery: q.Encode(),
	}

	l := struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}{
		Username: c.Username,
		Password: c.Password,
	}

	b := new(bytes.Buffer)
	if err := json.NewEncoder(b).Encode(l); err != nil {
		return err
	}

	req, err := http.NewRequest("POST", u.String(), b)
	req.Header.Add("Accept", "application/json")
	req.Header.Set("Content-Type", "application/json")
	if err != nil {
		return err
	}
	resp, err := c.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var msg message
	err = json.NewDecoder(resp.Body).Decode(&msg)

	if resp.StatusCode != http.StatusCreated {
		if err != nil {
			return fmt.Errorf("request failed: %d", resp.StatusCode)
		} else {
			return fmt.Errorf("request failed: %s", msg.Error.Message)
		}
	}

	if token, ok := resp.Header["Authorization"]; ok {
		c.token = token[0]
	}

	return nil
}

// PDUReboot powercycles the given outlet.
func PDUReboot(outlet int, host string, uname string, pwd string) error {
	conn := NewPDUConn(host, uname, pwd)
	if err := conn.Login(); err != nil {
		return err
	}
	defer conn.Logout()
	return conn.Loads(outlet, "Cycle")
}

// Loads changes the outlet state.
func (c *PDUConn) Loads(outlet int, state string) error {
	u := url.URL{
		Scheme: "https",
		Host:   c.Host,
		Path:   fmt.Sprintf("/api/device/loads/%d", outlet),
	}

	s := struct {
		LoadFireState string `json:"loadFireState"`
	}{
		LoadFireState: state,
	}

	b := new(bytes.Buffer)
	if err := json.NewEncoder(b).Encode(s); err != nil {
		return err
	}

	req, err := http.NewRequest("PUT", u.String(), b)
	if err != nil {
		return err
	}
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", c.token)
	req.Header.Set("Content-Type", "application/json")
	resp, err := c.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var msg message
	err = json.NewDecoder(resp.Body).Decode(&msg)

	if resp.StatusCode != http.StatusOK {
		if err != nil {
			return fmt.Errorf("request failed: %d", resp.StatusCode)
		} else {
			return fmt.Errorf("request failed: %s", msg.Error.Message)
		}
	}

	return nil
}

// Logout performs a logout and discards the authorization token.
func (c *PDUConn) Logout() error {
	u := url.URL{
		Scheme: "https",
		Host:   c.Host,
		Path:   "/api/AuthenticationControllers/logout",
	}

	req, err := http.NewRequest("POST", u.String(), nil)
	req.Header.Add("Accept", "application/json")
	req.Header.Add("Authorization", c.token)
	req.Header.Set("Content-Type", "application/json")
	if err != nil {
		return err
	}
	resp, err := c.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var msg message
	err = json.NewDecoder(resp.Body).Decode(&msg)

	if resp.StatusCode != http.StatusOK {
		if err != nil {
			return fmt.Errorf("request failed: %d", resp.StatusCode)
		} else {
			return fmt.Errorf("request failed: %s", msg.Error.Message)
		}
	}

	c.token = ""

	return nil
}

type PDUPowerManager struct {
	devicePort int
	pduIp      string
	pduUser    string
	pduPwd     string
}

func NewPDUPowerManager(ip string, user string, pwd string, port int) *PDUPowerManager {
	return &PDUPowerManager{
		devicePort: port,
		pduIp:      ip,
		pduUser:    user,
		pduPwd:     pwd,
	}
}

func (p *PDUPowerManager) Powercycle() error {
	return PDUReboot(p.devicePort, p.pduIp, p.pduUser, p.pduPwd)
}
