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

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"strings"
	"sync/atomic"
	"time"

	"go.fuchsia.dev/fuchsia/tools/lib/logger"
	"go.fuchsia.dev/fuchsia/tools/net/sshutil"
)

// Client is a wrapper around sl4f that supports auto-installing and starting
// sl4f on the target.
//
// If the target already has sl4f running, this client will not start a new
// instance.
//
// This client requires the target to contain the "pkgctl" binary and for the
// target to have the "run" and "sl4f" packages available at
// "fuchsia-pkg://host-target-testing-sl4f".
type Client struct {
	sshClient *sshutil.Client
	url       string
	repoName  string
	seq       uint64
}

func NewClient(ctx context.Context, sshClient *sshutil.Client, addr string, repoName string) (*Client, error) {
	c := &Client{
		sshClient: sshClient,
		repoName:  repoName,
		url:       fmt.Sprintf("http://%s", strings.ReplaceAll(addr, "%", "%25")),
	}

	if err := c.connect(ctx); err != nil {
		return nil, err
	}

	return c, nil
}

func (c *Client) connect(ctx context.Context) error {
	logger.Infof(ctx, "connecting to sl4f")

	// If an ssh connection re-establishes without a reboot, sl4f may already be running.
	pingCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
	if err := c.ping(pingCtx); err == nil {
		logger.Infof(ctx, "already connected to sl4f")
		cancel()
		return nil
	}
	cancel()

	// Start the CFv2 sl4f daemon.
	cmd := []string{"start_sl4f"}
	if err := c.sshClient.Run(ctx, cmd, os.Stdout, os.Stderr); err != nil {
		logger.Errorf(ctx, "unable to launch sl4f: %s", err)
		return err
	}

	// Wait a few seconds for it to respond to requests.
	pingCtx, cancel = context.WithTimeout(ctx, 30*time.Second)
	defer cancel()
	for pingCtx.Err() == nil {
		if err := c.ping(pingCtx); err == nil {
			return nil
		}
		time.Sleep(time.Second)
	}

	logger.Errorf(ctx, "unable to ping sl4f: %s", pingCtx.Err())
	return pingCtx.Err()
}

// ping attempts to perform an sl4f command that should always succeed if the server is up.
func (c *Client) ping(ctx context.Context) error {
	var response string

	if err := c.call(ctx, "device_facade.GetDeviceName", nil, &response); err != nil {
		return err
	}

	return nil
}

func (c *Client) call(ctx context.Context, method string, params interface{}, result interface{}) error {
	type request struct {
		Method string      `json:"method"`
		Id     string      `json:"id"`
		Params interface{} `json:"params"`
	}

	id := fmt.Sprintf("%d", atomic.AddUint64(&c.seq, 1))
	body, err := json.Marshal(request{
		Method: method,
		Id:     id,
		Params: params,
	})
	if err != nil {
		return err
	}

	req, err := http.NewRequestWithContext(ctx, "GET", c.url, bytes.NewReader(body))
	if err != nil {
		return err
	}
	req.Header.Add("Content-Type", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var response struct {
		Id     string          `json:"id"`
		Result json.RawMessage `json:"result"`
		Error  json.RawMessage `json:"error"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
		return err
	}

	// TODO(https://fxbug.dev/42115892) sl4f currently response with different id values, but
	// over HTTP, we can safely assume this response is for the request we
	// made over this connection
	//if response.Id != id {
	//	return fmt.Errorf("server responded with invalid ID: %q != %q", id, response.Id)
	//}

	var response_error string
	if err := json.Unmarshal(response.Error, &response_error); err != nil {
		return fmt.Errorf("unable to decode error from server: %s", response.Error)
	}

	if response_error != "" {
		return fmt.Errorf("error from server: %s", response_error)
	}

	if err := json.Unmarshal(response.Result, result); err != nil {
		return err
	}

	return nil
}
