package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"

	"github.com/pingcap-inc/lark-bots/v2/pkg/util"
)

type ReqPurgeRequestBody struct {
	Name     string   `json:"name"`
	FileURLs []string `json:"fileUrls"`
	DirURLs  []string `json:"dirUrls"`
	Action   string   `json:"action"`
	Target   string   `json:"target"`
}

type RespPurgeStatusBody struct {
	SubmissionTime time.Time `json:"submissionTime"`
	FinishTime     time.Time `json:"finishTime"`
	Status         string    `json:"status"`
	FileUrls       []string  `json:"fileUrls"`
	FileHeaders    []struct {
		Name  string `json:"name"`
		Value string `json:"value"`
	} `json:"fileHeaders"`
	DirUrls      []string `json:"dirUrls"`
	Action       string   `json:"action"`
	Target       string   `json:"target"`
	ApiRequestId string   `json:"apiRequestId"`
	CustomerId   int      `json:"customerId"`
	SuccessRate  float32  `json:"successRate"`
}

// refreshCDNPageCache calls Quantil CDN API to purge the website page content cached in the edge
func createPurgeReqeust(urls []string, dirulrs []string) (string, error) {
	purgeAPIEndpoint := "https://ngapi.quantil.com/cdnapi/purges"
	t := time.Now()
	date := t.Format(time.RFC1123)
	user := "pingcap"
	pswd := util.GetHMACSignatureSHA1(date, apiKey)
	task := fmt.Sprintf("create_purge_request_task_%s", t.Format(time.RFC3339))
	body := &ReqPurgeRequestBody{
		Name:     task,
		FileURLs: urls,
		DirURLs:  dirulrs,
		Action:   "Delete",
		Target:   "Production",
	}
	jsonData, err := json.Marshal(body)
	if err != nil {
		return "-1", err
	}

	request, err := http.NewRequest("POST", purgeAPIEndpoint, bytes.NewBuffer(jsonData))
	if err != nil {
		return "-1", err
	}
	request.SetBasicAuth(user, pswd)
	request.Header.Set("Date", date)
	request.Header.Set("Content-Type", "application/json")
	request.Header.Set("Accept", "application/json")

	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return "-1", err
	}
	defer response.Body.Close()

	// fmt.Println("response Status:", response.Status)
	fmt.Println("response Headers:", response.Header)
	b, _ := ioutil.ReadAll(response.Body)
	fmt.Println("response Body:", string(b))

	if response.Status != "201 Created" {
		return "-1", fmt.Errorf("create purge request failed")
	}

	if v, found := response.Header["Location"]; found {
		if len(v) == 0 || v[0] == "" {
			return "-1", fmt.Errorf("bad response header: empty location")
		}
		s := strings.Split(v[0], "/")
		id := s[len(s)-1]
		if id == "" {
			return "-1", fmt.Errorf("bad response header: empty task id")
		}
		return id, nil
	} else {
		return "-1", fmt.Errorf("bad response header: no location")
	}
}

func getPurgeRequestStatus(taskid string) (status string, rate float32, files []string, dirs []string, finishTime time.Time, err error) {
	purgeStatusAPIEndpoint := "https://ngapi.quantil.com/cdnapi/purges/" + taskid
	t := time.Now()
	date := t.Format(time.RFC1123)
	user := "pingcap"
	pswd := util.GetHMACSignatureSHA1(date, apiKey)

	request, err := http.NewRequest("GET", purgeStatusAPIEndpoint, nil)
	if err != nil {
		return
	}
	request.SetBasicAuth(user, pswd)
	request.Header.Set("Date", date)
	request.Header.Set("Content-Type", "application/json")
	request.Header.Set("Accept", "application/json")

	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return
	}
	defer response.Body.Close()

	// fmt.Println("response Status:", response.Status)
	fmt.Println("response Headers:", response.Header)
	b, _ := ioutil.ReadAll(response.Body)
	fmt.Println("response Body:", string(b))

	if response.Status != "200 OK" {
		err = fmt.Errorf("get purge request status failed, return status: %s", response.Status)
		return
	}

	res := RespPurgeStatusBody{}
	err = json.Unmarshal(b, &res)
	if err == nil {
		status = res.Status
		rate = res.SuccessRate
		files = res.FileUrls
		dirs = res.DirUrls
		finishTime = res.FinishTime
	}
	return
}
