package main

import (
	"bytes"
	"crypto/rand"
	"encoding/json"
	"fmt"
	"io"
	"net/http"

	"golang.org/x/crypto/blake2s"
	"golang.org/x/crypto/chacha20poly1305"
)

type EnvironmentData struct {
	Temp     float64 `json:"t" binding:"required"`
	Humidity float64 `json:"h" binding:"required"`
}

const passcode = "pass2"
const salt = "ENVIRONMENT"

func main() {
	data := EnvironmentData{Temp: 25, Humidity: 40}
	b, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	pass, err := DeriveKey(passcode)
	if err != nil {
		panic(err)
	}

	aead, err := chacha20poly1305.New([]byte(pass))
	if err != nil {
		panic(err)
	}

	iv := make([]byte, chacha20poly1305.NonceSize)
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		panic(err)
	}

	cypher := aead.Seal(nil, iv, b, nil)
	cypher = append(iv, cypher...)
	request, err := http.NewRequest(http.MethodPut, "http://localhost:8080/data/authed/7701238505945920037", bytes.NewReader(cypher))

	if err == nil {
		resp, err := http.DefaultClient.Do(request)
		if err != nil {
			panic(err)
		}
		defer resp.Body.Close()
		fmt.Printf("Sent, code: %s", resp.Status)
	} else {
		panic(err)
	}
}

func DeriveKey(passcode string) ([]byte, error) {

	hash, err := blake2s.New256(nil)
	if err != nil {
		return nil, err
	}
	hash.Write([]byte(salt))
	hash.Write([]byte(passcode))

	fmt.Printf("SALT %s PASS %s\n", salt, passcode)

	return hash.Sum(nil), nil
}
