package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"sync"

	"gopkg.in/yaml.v2"
)

type Config struct {
	ServerAddress     string `yaml:"server_address" json:"server_address"`
	MaxRetries        int    `yaml:"max_retries" json:"max_retries"`
	ReconnectInterval int    `yaml:"reconnect_interval" json:"reconnect_interval"`
	ReadTimeout       int    `yaml:"read_timeout" json:"read_timeout"`
	RestAPIEndpoint   string `yaml:"rest_api_endpoint" json:"rest_api_endpoint"`
}

var (
	config     Config
	configLock sync.RWMutex
)

func loadConfig() error {
	data, err := ioutil.ReadFile("config.yaml")
	if err != nil {
		return err
	}

	configLock.Lock()
	defer configLock.Unlock()

	return yaml.Unmarshal(data, &config)
}

func saveConfig() error {
	configLock.RLock()
	defer configLock.RUnlock()

	data, err := yaml.Marshal(config)
	if err != nil {
		return err
	}

	return ioutil.WriteFile("config.yaml", data, 0644)
}

func getConfigHandler(w http.ResponseWriter, r *http.Request) {
	configLock.RLock()
	defer configLock.RUnlock()

	json.NewEncoder(w).Encode(config)
}

func updateConfigHandler(w http.ResponseWriter, r *http.Request) {
	var newConfig Config
	if err := json.NewDecoder(r.Body).Decode(&newConfig); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	configLock.Lock()
	config = newConfig
	configLock.Unlock()

	if err := saveConfig(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}

func loginHandler(w http.ResponseWriter, r *http.Request) {
	// 실제 구현에서는 사용자 인증을 처리해야 합니다.
	// 여기서는 간단한 예시만 제공합니다.
	username := r.FormValue("username")
	password := r.FormValue("password")

	if username == "admin" && password == "password" {
		// 로그인 성공 시 세션 생성 또는 토큰 발급
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, "Login successful")
	} else {
		http.Error(w, "Invalid credentials", http.StatusUnauthorized)
	}
}

func main() {
	if err := loadConfig(); err != nil {
		panic(err)
	}

	http.HandleFunc("/login", loginHandler)
	http.HandleFunc("/config", func(w http.ResponseWriter, r *http.Request) {
		// 여기에 인증 검사 로직을 추가해야 합니다.
		switch r.Method {
		case http.MethodGet:
			getConfigHandler(w, r)
		case http.MethodPost:
			updateConfigHandler(w, r)
		default:
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		}
	})

	// 정적 파일 제공을 위한 파일 서버 설정
	fs := http.FileServer(http.Dir("static"))

	// 루트 경로에 대한 핸들러 추가
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path == "/" {
			http.ServeFile(w, r, "static/index.html")
		} else {
			fs.ServeHTTP(w, r)
		}
	})

	fmt.Println("Server is running on http://localhost:8081")
	http.ListenAndServe(":8081", nil)

}
