package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strings"

	"github.com/tidbcloud/config-service/sdk/api"
)

const (
	ClusterFile = "cluster.json"
	BackupFile  = "backup.json"
	RestoreFile = "restore.json"

	ClusterSharedFile = "cluster-shared.json"
)

var listenPort = ":8080"

func init() {
	flag.StringVar(&listenPort, "listen-port", listenPort, "the server listen port")
}

func DescribeClusterConfigOutput(w http.ResponseWriter, req *http.Request) {
	log.Printf("get request: %v", req)

	var input api.DescribeClusterConfigInput
	if err := json.NewDecoder(req.Body).Decode(&input); err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "DescribeClusterConfigOutput Err: %v", err)
		return
	}

	file := ClusterFile
	if len(input.Components) > 0 && strings.Contains(input.Components[0].InstanceType, "shared-tier") {
		file = ClusterSharedFile
	}
	b, err := ioutil.ReadFile(file)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "DescribeClusterConfigOutput Err: %v", err)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	if _, err = w.Write(b); err != nil {
		log.Printf("server write err: %v", err)
	}
}

func DescribeBackupConfigOutput(w http.ResponseWriter, req *http.Request) {
	log.Printf("get request: %v", req)

	b, err := ioutil.ReadFile(BackupFile)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "DescribeBackupConfigOutput Err: %v", err)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	if _, err = w.Write(b); err != nil {
		log.Printf("server write err: %v", err)
	}
}

func DescribeRestoreConfigOutput(w http.ResponseWriter, req *http.Request) {
	log.Printf("get request: %v", req)

	b, err := ioutil.ReadFile(RestoreFile)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		fmt.Fprintf(w, "DescriberRestoreConfigOutput Err: %v", err)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	if _, err = w.Write(b); err != nil {
		log.Printf("server write err: %v", err)
	}
}

func main() {
	flag.Parse()

	log.Printf("config service mock start listening %s", listenPort)

	http.HandleFunc("/api/v1/cluster/configuration", DescribeClusterConfigOutput)
	http.HandleFunc("/api/v1/backup/configuration", DescribeBackupConfigOutput)
	http.HandleFunc("/api/v1/restore/configuration", DescribeRestoreConfigOutput)
	if err := http.ListenAndServe(listenPort, nil); err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}
