package main

import (
	"flag"
	"git.cacert.org/cacert-gosigner/datastructures"
	"git.cacert.org/cacert-gosigner/shared"
	"log"
	"time"

	"github.com/goburrow/serial"
)

var (
	address  string
	baudrate int
	databits int
	stopbits int
	parity   string
	message  string
)

func main() {
	flag.StringVar(&address, "a", "/dev/ttyUSB0", "address")
	flag.IntVar(&baudrate, "b", 115200, "baud rate")
	flag.IntVar(&databits, "d", 8, "data bits")
	flag.IntVar(&stopbits, "s", 1, "stop bits")
	flag.StringVar(&parity, "p", "N", "parity (N/E/O)")
	flag.StringVar(&message, "m", "serial", "message")
	flag.Parse()

	config := serial.Config{
		Address:  address,
		BaudRate: baudrate,
		DataBits: databits,
		StopBits: stopbits,
		Parity:   parity,
		Timeout:  30 * time.Second,
	}
	log.Printf("connecting %+v", config)
	port, err := serial.Open(&config)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("connected")
	defer func() {
		err := port.Close()
		if err != nil {
			log.Fatal(err)
		}
		log.Println("closed")
	}()

	if _, err = port.Write([]byte{0x02}); err != nil {
		log.Fatal(err)
	}

	resp := make([]byte, 1)
	if _, err = port.Read(resp); err != nil {
		log.Fatal(err)
	}

	request := datastructures.NewNulRequest()
	timeout := time.After(2700 * time.Millisecond)
	errorChannel := make(chan error, 1)
	responseChannel := make(chan *datastructures.SignerResponse, 1)

	go func() {
		if response, err := SendRequest(&port, request); err != nil {
			errorChannel <- err
		} else {
			responseChannel <- response
		}
	}()

	select {
	case <-timeout:
		log.Fatal("timeout")
	case err := <-errorChannel:
		log.Fatal(err)
	case response := <- responseChannel:
		if err := Process(response); err != nil {
			log.Fatal(err)
		}
	}
	requestBytes := request.Serialize()

	if _, err = port.Write(requestBytes); err != nil {
		log.Fatal(err)
	}

	if _, err = port.Write([]byte{datastructures.CalculateXorCheckSum([][]byte{requestBytes})}); err != nil {
		log.Fatal(err)
	}

	if _, err = port.Write([]byte(shared.MagicTrailer)); err != nil {
		log.Fatal(err)
	}
}

func Process(response *datastructures.SignerResponse) error {
	return nil
}

func SendRequest(port *serial.Port, request *datastructures.SignerRequest) (*datastructures.SignerResponse, error) {
	return nil, nil
}