package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/joshuaferrara/go-satellite"
	"net"
	"strconv"
	"time"
)

const (
	// Server port
	Port = ":55555"
	// Server IP
	IP = "127.0.0.1"
)

var DebugFlag *bool

func main() {
	DebugFlag = flag.Bool("d", false, "run program with local config and with all the prints")
	flag.Parse()
	fmt.Println(*DebugFlag)

	rotctldBuf := openAddr(IP + Port)

	// Read response
	//response, err := rw.ReadString('\n')
	//if err != nil {
	//	dPrintln("Failed to read the reply: '"+response+"'")
	//}

	year, month, day, hour, min, sec := getUTC()
	sat := satellite.TLEToSat("1 25544U 98067A   18088.93511921  .00004874  00000-0  80700-4 0  9998",
		"2 25544  51.6414  53.8028 0001446 273.2833 187.1736 15.54165179106196", "wgs84")
	jdate := satellite.JDay(year, month, day, hour, min, sec)
	satPos, _ := satellite.Propagate(sat, year, month, day, hour, min, sec)
	dPrintln(jdate)
	angles := satellite.ECIToLookAngles(satPos, satellite.LatLong{40.110588, -88.207270}, 0.220, jdate)
	writeToRotator(rotctldBuf, angles.Az, angles.El)
	dPrintln(angles.Az*satellite.RAD2DEG, angles.El*satellite.RAD2DEG, angles.Rg)
}

// Opens tcp connection on given address
// Returns r/w buffer that sits on top of the connection
func openAddr(addr string) *bufio.ReadWriter {
	dPrintln(addr)
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		dPrintln("Dialing " + addr + " failed")
		//TODO exit code here
	}
	return bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
}

// Takes angles in radians and sends them over tcp to the rotator controller
func writeToRotator(rotctldBuf *bufio.ReadWriter, az float64, el float64) {
	az = az * satellite.RAD2DEG
	el = el * satellite.RAD2DEG
	_, err := rotctldBuf.WriteString("P " + f64ToString(az) + " " + f64ToString(el) + "\n")

	if err != nil {
		dPrintln("Couldn't write to buffer")
		//TODO exit code here
	}

	err = rotctldBuf.Flush()
	if err != nil {
		dPrintln("Couldn't flush bufferd tcp port")
		//TODO exit code here
	}
}

// getUTC returns the the current utc time
// returns year, month, day, hour, min, sec as ints
func getUTC() (year, month, day, hour, min, sec int) {
	now := time.Now().UTC()
	year, month_t, day := now.UTC().Date()
	month = int(month_t)
	hour = now.Hour()
	min = now.Minute()
	sec = now.Second()
	return
}

// dPrintln prints to stdout only if debug flag is passed to program
func dPrintln(i ...interface{}) {
	if *DebugFlag {
		fmt.Println(i)
	}
}

func f64ToString(input_num float64) string {
	// to convert a float number to a string
	return strconv.FormatFloat(input_num, 'f', 2, 64)
}