package main

import (
	"encoding/json"
	"fmt"
	"golang.org/x/crypto/bcrypt"
	"io/ioutil"
	"os"
	"time"
)

var configFile = "config.json"
var defaultAdmin = &configAdmin{
	"admin", []byte("$2a$14$iAOnPBQp6rlPIMGmTzH8qef1pK6tgl9yIfSLlZ2Z9IzIYn6hQPawi"),
}

var config = &configMain{
	Admins: map[string]*configAdmin{
		"admin": defaultAdmin,
	},
	Boards: map[uint16]*configBoard{},
	Secret: RandString(24),
	Influx: nil,
}

type configInflux struct {
	Domain string	`json:"domain"`
	Database string `json:"database"`
	Username string `json:"username"`
	Password string `json:"password"`
}

type configMain struct{
	Admins map[string]*configAdmin `json:"admins"`
	Boards map[uint16]*configBoard `json:"boards"`
	Secret string `json:"secret"`
	Influx *configInflux `json:"influx"`
}

type configAdmin struct{
	Username string `json:"user"`
	Hash []byte		`json:"hash"`
}

func (a *configAdmin) newPassword(pass string) error {
	var err error
	a.Hash, err = bcrypt.GenerateFromPassword([]byte(pass), 14)
	return err
}

func (a *configAdmin) checkPassword(pass string) bool {
	err := bcrypt.CompareHashAndPassword(a.Hash, []byte(pass))
	return err == nil
}

type configBoard struct{
	ID uint16				`json:"ID"`
	KEY []byte				`json:"KEY"`
	KEY16 string			`json:"KEY16"`
	LastSeen time.Time 		`json:"LastSeen"`
}

func loadConfig() {
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		fmt.Println("No config file. Creating a new one.")
		saveConfig()
		return
	}
	jsonFile, err := os.Open(configFile)
	errCheckExit(err, "Unable to open config file")
	defer jsonFile.Close()
	byteValue, _ := ioutil.ReadAll(jsonFile)
	err = json.Unmarshal(byteValue, config)
	errCheck(err, "Failed to unmarshal config")
}

func saveConfig() {
	jsonValue, _ := json.Marshal(config)
	err := ioutil.WriteFile(configFile, jsonValue, 0644)
	errCheck(err, "Failed to write config")
}