package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"

	"git.parravidales.es/parra/drone-ntfy/pkg/model"
	"github.com/caarlos0/env/v7"
	"github.com/joho/godotenv"
)

type Data struct {
	App   model.App
	Drone model.Drone
	Ci    model.Ci
}

func main() {

	data := loadData()

	buildAppData(&data)
	addResultToTags(&data)
	sendNotification(&data)
}

func loadData() Data {

	envErr := godotenv.Load()
	if envErr == nil {
		fmt.Printf("loaded .env file.")
	}

	data := Data{
		App:   model.App{},
		Drone: model.Drone{},
		Ci:    model.Ci{},
	}
	loadDataFromEnv(&data.App)
	loadDataFromEnv(&data.Drone)
	loadDataFromEnv(&data.Ci)

	data.App.Tags = append(data.App.DefaultTags, data.App.Tags...)

	return data
}

func loadDataFromEnv(data any) {
	err := env.Parse(data)
	if err != nil {
		log.Fatalf("unable to parse environment variables: %e", err)
	}
}

func buildAppData(data *Data) {

	data.App.Title = data.Drone.RepoName + "Build #" + data.Drone.BuildNumber + " " + data.Drone.BuildStatus

	if strings.Contains(data.Ci.CommitRef, "refs/tags/") {
		data.App.Tags = append(data.App.Tags, data.Drone.Tag)
		data.App.Message = "Tag " + data.Drone.Tag + " created"
	} else {
		data.App.Tags = append(data.App.Tags, data.Drone.RepoName+"/"+data.Ci.CommitBranch)
		data.App.Message = "[" + data.Ci.CommitSha[0:8] + "] " + data.Ci.CommitMessage
	}
}

func addResultToTags(data *Data) {

	if data.Drone.BuildStatus == "success" {
		data.App.Tags = append(data.App.Tags, "white_check_mark")
	} else if data.Drone.BuildStatus == "failure" {
		data.App.Tags = append(data.App.Tags, "x")
	} else {
		data.App.Tags = append(data.App.Tags, "grey_question")
	}
}

func sendNotification(data *Data) {

	req, _ := http.NewRequest("POST",
		data.App.BaseUrl+"/"+data.App.Topic,
		strings.NewReader(data.App.Message))

	if data.App.Token != "" {
		req.Header.Add("Authorization", "Bearer "+data.App.Token)
	} else {
		req.SetBasicAuth(data.App.Username, data.App.Password)
	}
	req.Header.Set("Title", data.App.Title)
	req.Header.Set("Priority", data.App.Priority)
	req.Header.Set("Tags", strings.Join(data.App.Tags, ","))
	req.Header.Set("Actions", getActions(data))
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("error trying to notify the result. Error: %+v", err)
	}
	if res.StatusCode != 200 {
		log.Fatalf("error from server. HTTP status: %d. Error: %e", res.StatusCode, err)
	}
}

func getActions(data *Data) string {
	var buildLink = "view, Build, " + data.Drone.BuildLink
	if strings.Contains(data.Ci.CommitRef, "refs/tags/") {
		return buildLink
	}
	return buildLink + "; view, Changes, " + data.Drone.CommitLink
}