package main

import (
	"flag"
	"os"

	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"github.com/tidbcloud/cost-collect/api"
	"github.com/tidbcloud/cost-collect/pkg/cloud/aws"
	"github.com/tidbcloud/cost-collect/pkg/cloud/gcp"
	"github.com/tidbcloud/cost-collect/pkg/config"
	"github.com/tidbcloud/cost-collect/pkg/cost"
	"github.com/tidbcloud/cost-collect/pkg/global"
)

var addr string
var configPath string
var logLevel string

func initParse() {
	flag.StringVar(&addr, "listen-address", ":8080", "The address to listen on for HTTP requests.")
	flag.StringVar(&configPath, "config-file", "/etc/cost-collector.conf", "The file for config.")
	flag.StringVar(&logLevel, "log-level", "", "The config level.")
	flag.Parse()
}

func initManager() (*cost.Manager, error) {
	manager := cost.NewManager()

	// gcp
	gcpClient, err := gcp.NewBillingClient(viper.GetString("gcp.provider_project_id"),
		viper.GetString("gcp.location"),
		gcp.BigQuerySharedParam{
			Table:       viper.GetString("gcp.bigquery_table_name"),
			BillProject: viper.GetString("gcp.bill_project_id"),
		},
	)
	if err != nil {
		return nil, err
	}

	viper.SetDefault("aws.wait_time", 3)
	// aws
	awsClient, err := aws.NewBillingClient(
		viper.GetString("aws.output_bucket"),
		viper.GetInt("aws.wait_time"),
		aws.AthenaSharedParam{
			Database: viper.GetString("aws.database"),
			Table:    viper.GetString("aws.table"),
		},
	)
	if err != nil {
		return nil, err
	}

	err = manager.Register("gcp", gcpClient)
	if err != nil {
		return nil, err
	}

	err = manager.Register("aws", awsClient)
	if err != nil {
		return nil, err
	}

	return manager, nil
}

func main() {
	initParse()

	if logLevel == "" {
		viper.SetDefault("global.log_level", "info")
		logLevel = viper.GetString("global.log_level")
	}

	// init config
	err := config.SetLogLevel(logLevel)
	if err != nil {
		panic(err)
	}

	err = config.InitViper(configPath)
	if err != nil {
		panic(err)
	}

	manger, err := initManager()
	if err != nil {
		panic(err)
	}

	engine := gin.Default()

	engine.GET("/ping", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	engine.GET("/version", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"version": global.Version,
		})
	})

	v1 := engine.Group("/api/v1")
	gin.DefaultWriter = os.Stdout

	costAPI := api.NewProviderCostAPI(manger)
	costAPI.Load(v1)

	engine.Run(addr)

}
