package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"github.com/webview/webview"
)

var lamp0IsOn bool = false
var lamp1IsOn bool = false

var emulatedServiceStated []int = []int{0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 1, 0, 1}

type GlobalStatus struct {
	Lamp0 bool
	Lamp1 bool
}

func main() {
	//Clear terminal screen
	cmd := exec.Command("clear") //Linux example, its tested
	cmd.Stdout = os.Stdout
	cmd.Run()

	//Create a local webserver
	go func() {
		fs := http.FileServer(http.Dir("./web"))
		http.Handle("/", fs)
		http.HandleFunc("/~/mn-cse/mn-name/sm_sensor_1/sm_DATA", cinHandler)
		http.HandleFunc("/~/mn-cse/", createAEHandler)
		http.HandleFunc("/~/mn-cse/mn-name/sm_sensor_1", oprHandler)
		http.HandleFunc("/getStatus", statusHandler)

		http.ListenAndServe(":8282", nil)
	}()

	input := ""
	for input != "exit" {
		input = StringPrompt("osgi> ")
		EmulateInput(input)
	}

}

func EmulateInput(input string) {
	if input == "ss" {
		fakeSSOutput, _ := ioutil.ReadFile("ssOutput.txt")
		output := string(fakeSSOutput)
		lines := strings.Split(output, "\n")
		for i := 31; i < 57; i++ {
			status := "RESOLVED"
			if emulatedServiceStated[i-31] == 0 {

			} else if emulatedServiceStated[i-31] == 1 {
				status = "ACTIVE  "
			} else if emulatedServiceStated[i-31] == 2 {
				status = "STARTING"
			}
			fmt.Println(strconv.Itoa(i) + "          " + status + "     " + lines[i-31])
		}
	} else if input == "start 41" {
		fakeStartOutput, _ := ioutil.ReadFile("startOutput.txt")
		output := string(fakeStartOutput)
		lines := strings.Split(output, "\n")
		for i := 0; i < len(lines); i++ {
			if strings.TrimSpace(lines[i]) == "" {
				//Give it a break to emulate loading
				delayTime := rand.Intn(500-200) + 200
				time.Sleep(time.Duration(delayTime) * time.Millisecond)
				fmt.Println("")
			} else {
				fmt.Println(lines[i])
			}
		}

		//Start the UI thread (Blocking)
		debug := true
		w := webview.New(debug)
		defer w.Destroy()
		w.SetTitle("Sample Simulated IPE")
		w.SetSize(582, 580, webview.HintFixed)
		w.Navigate("http://127.0.0.1:8282")
		w.Run()

	}
}

func StringPrompt(label string) string {
	var s string
	r := bufio.NewReader(os.Stdin)
	for {
		fmt.Fprint(os.Stderr, label+" ")
		s, _ = r.ReadString('\n')
		if s != "" {
			break
		}
	}
	return strings.TrimSpace(s)
}

func statusHandler(w http.ResponseWriter, r *http.Request) {
	currentStatus := GlobalStatus{
		lamp0IsOn,
		lamp1IsOn,
	}

	js, _ := json.Marshal(currentStatus)
	w.Write(js)
}

func oprHandler(w http.ResponseWriter, r *http.Request) {
	time.Sleep(300 * time.Millisecond)
	if r.Method == http.MethodDelete {
		w.WriteHeader(http.StatusNotFound)
		return
	} else if r.Method == http.MethodPost {
		/*
			content, err := ioutil.ReadAll(r.Body)
			if err != nil {
				panic(err)
			}

			log.Println("Create CNT:", string(content))
		*/
		w.WriteHeader(http.StatusCreated)
		return
	}
}

func createAEHandler(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusCreated)
}

func cinHandler(w http.ResponseWriter, r *http.Request) {
	time.Sleep(300 * time.Millisecond)
	content, err := ioutil.ReadAll(r.Body)
	if err != nil {
		panic(err)
	}

	if strings.Contains(string(content), "ClBSRUZJWCBzb3NhOiA8aHR0cDovL3d3dy53My5vcmcvbnMvc29zYS8+ClBSRUZJWCBleHE6IDxodHRwOi8vZXhhbXBsZS5vcmcvbnMjPgpTRUxFQ1QgP3Jlc3VsdApXSEVSRSB7CiAgICBleHE6b2JzMDA2IGEgc29zYTpPYnNlcnZhdGlvbjsKICAgICAgICBzb3NhOmhhc1Jlc3VsdCA/dmFsCiAgICBCSU5EICgKICAgICAgQ09BTEVTQ0UoCiAgICAgICAgSUYoP3ZhbCA+PSAzMCwgImh0dHA6Ly8xMjcuMC4wLjE6ODA4MC9+L21uLWNzZS9tbi1uYW1lL0xBTVBfMT9vcD1zZXRPbiZsYW1waWQ9TEFNUF8xIiwgMS8wKSwKICAgICAgICBJRig/dmFsIDw9IDI1LCAiaHR0cDovLzEyNy4wLjAuMTo4MDgwL34vbW4tY3NlL21uLW5hbWUvTEFNUF8xP29wPXNldE9mZiZsYW1waWQ9TEFNUF8xIiwgMS8wKSwKICAgICAgICAiRVJST1IiCiAgICAgICkgQVMgP3Jlc3VsdAogICAgKQp9Cg==") {
		//Set lightbulb 0 to on
		lamp0IsOn = !lamp0IsOn
	}

	//log.Println("CREATE CIN", string(content))
	w.WriteHeader(http.StatusCreated)
}

func mv(r *http.Request, getParamter string, postMode bool) (string, error) {
	if postMode == false {
		//Access the paramter via GET
		keys, ok := r.URL.Query()[getParamter]

		if !ok || len(keys[0]) < 1 {
			//log.Println("Url Param " + getParamter +" is missing")
			return "", errors.New("GET paramter " + getParamter + " not found or it is empty")
		}

		// Query()["key"] will return an array of items,
		// we only want the single item.
		key := keys[0]
		return string(key), nil
	} else {
		//Access the parameter via POST
		r.ParseForm()
		x := r.Form.Get(getParamter)
		if len(x) == 0 || x == "" {
			return "", errors.New("POST paramter " + getParamter + " not found or it is empty")
		}
		return string(x), nil
	}

}
