package remote

import (
	"crypto/md5"
	"encoding/json"
	"testing"
)

func TestRemoteClient_noPayload(t *testing.T) {
	s := &State{
		Client: nilClient{},
	}
	if err := s.RefreshState(); err != nil {
		t.Fatal("error refreshing empty remote state")
	}
}

// nilClient returns nil for everything
type nilClient struct{}

func (nilClient) Get() (*Payload, error) { return nil, nil }

func (c nilClient) Put([]byte) error { return nil }

func (c nilClient) Delete() error { return nil }

// mockClient is a client that tracks persisted state snapshots only in
// memory and also logs what it has been asked to do for use in test
// assertions.
type mockClient struct {
	current []byte
	log     []mockClientRequest
}

type mockClientRequest struct {
	Method  string
	Content map[string]interface{}
}

func (c *mockClient) Get() (*Payload, error) {
	c.appendLog("Get", c.current)
	if c.current == nil {
		return nil, nil
	}
	checksum := md5.Sum(c.current)
	return &Payload{
		Data: c.current,
		MD5:  checksum[:],
	}, nil
}

func (c *mockClient) Put(data []byte) error {
	c.appendLog("Put", data)
	c.current = data
	return nil
}

func (c *mockClient) Delete() error {
	c.appendLog("Delete", c.current)
	c.current = nil
	return nil
}

func (c *mockClient) appendLog(method string, content []byte) {
	// For easier test assertions, we actually log the result of decoding
	// the content JSON rather than the raw bytes. Callers are in principle
	// allowed to provide any arbitrary bytes here, but we know we're only
	// using this to test our own State implementation here and that always
	// uses the JSON state format, so this is fine.

	var contentVal map[string]interface{}
	if content != nil {
		err := json.Unmarshal(content, &contentVal)
		if err != nil {
			panic(err) // should never happen because our tests control this input
		}
	}
	c.log = append(c.log, mockClientRequest{method, contentVal})
}

// mockClientForcePusher is like mockClient, but also implements
// EnableForcePush, allowing testing for this behavior
type mockClientForcePusher struct {
	current []byte
	force   bool
	log     []mockClientRequest
}

func (c *mockClientForcePusher) Get() (*Payload, error) {
	c.appendLog("Get", c.current)
	if c.current == nil {
		return nil, nil
	}
	checksum := md5.Sum(c.current)
	return &Payload{
		Data: c.current,
		MD5:  checksum[:],
	}, nil
}

func (c *mockClientForcePusher) Put(data []byte) error {
	if c.force {
		c.appendLog("Force Put", data)
	} else {
		c.appendLog("Put", data)
	}
	c.current = data
	return nil
}

// Implements remote.ClientForcePusher
func (c *mockClientForcePusher) EnableForcePush() {
	c.force = true
}

func (c *mockClientForcePusher) Delete() error {
	c.appendLog("Delete", c.current)
	c.current = nil
	return nil
}
func (c *mockClientForcePusher) appendLog(method string, content []byte) {
	var contentVal map[string]interface{}
	if content != nil {
		err := json.Unmarshal(content, &contentVal)
		if err != nil {
			panic(err) // should never happen because our tests control this input
		}
	}
	c.log = append(c.log, mockClientRequest{method, contentVal})
}
