package main

import (
	"fmt"
	"time"
	"bufio"
	"os"
	"strings"
	"net"
	"log"

	"example.com/genji"
)

var UserCode int32 = 1234

func DetectGenjiDevChange(){

	addr,err := net.ResolveUDPAddr("udp", "localhost:5900")
	if err != nil{
		log.Fatal("ResolveUPDAddr error")
	}

	genji.RegisterGenjiCallbackPort(5900)

	conn,err := net.ListenUDP("udp", addr)
	if err != nil{
		log.Fatal("ListenUPD error")
	}

	defer conn.Close()

	buffer := make([]byte, 32)

	conn.SetDeadline(time.Now().Add(500*time.Millisecond))

	for{

		n, _,err := conn.ReadFromUDP(buffer)
		if err != nil{
			if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				continue
			}else{
				fmt.Println("ReadFromUDP Error")
				break;
			}
		}
		msg := string(buffer[:n])
		if msg == "removed"{
			conn.Close()
			fmt.Printf("\n    ***** Genji removed. Exiting in 2 sec... ****\n")
			time.Sleep(2 * time.Second)
			os.Exit(1)
		}
	}

}

func keyInString(prompt string) (text string){

	reader := bufio.NewReader(os.Stdin)
	fmt.Println( prompt)
	_text, _ := reader.ReadString('\n') 

	text = strings.TrimSpace(_text)

	return
}

func RSAEncTest(UserCode int32, dNr int16, plainText string) bool{

	// create a key pair at key index 1 at dNr
	if createKeyPair(UserCode, 1,  dNr) == false{
		return false
	}
	
	// load private/public keys from key files at key index 2 at dNr
	if importKeyPair(UserCode, 2, dNr) == false {
		return false
	}

	if( len(plainText) > 0)	{
		//encrypt/decrypt test using the keypair at KeyIndex 1
		if RSAEncDec(UserCode, 1, dNr, plainText) == false {
			return false
		}
		time.Sleep(2 * time.Second)

		//encrypt/decrypt test using the keypair at KeyIndex 2
		if RSAEncDec(UserCode, 2, dNr, plainText) == false {
			return false
		}
		time.Sleep(2 * time.Second)
	}

	return true
}


func main() {

	// check if any Genji is connected
	// return the number of Genji connected
	var count int16 = detectGenji(UserCode )
	if( count < 1){
		return
	}

	go DetectGenjiDevChange()
	
	var dNr int16

	// loop over the connected Genji
	for dNr = 1 ; dNr <= count ; dNr++ {

		fmt.Println("\n\n//////////////// Genji No.", dNr, "////////////////")

		LEDTest(dNr)

		if false == Data2test(UserCode, dNr){
			return
		}

		fmt.Println("\n***** Enter Text for RSA Encrypt Test *****")
		plainText := keyInString("")

		if len(plainText) > 0{
			if RSAEncTest(UserCode, dNr, plainText) == false{
				return
			}
		}else{
			fmt.Println("Skipping RSA Encrypt/Decrypt test")
		}

		fmt.Println("\n***** Enter Text for RSA Sign/Verify Test *****")
		msg := keyInString("")

		if len(msg) > 0{
			if false == RSASigVerify(UserCode, 1, dNr, msg ) {
				return
			}
			if false == RSASigVerify(UserCode, 2, dNr, msg ) {
				return
			}
		}else{
			fmt.Println("Skipping RSA Sign/Verify test")
		}

		if false == randTest(UserCode, dNr){
			return
		}

	}

}


