package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"git.pbiernat.dev/egommerce/go-api-pkg/fluentd"
	"git.pbiernat.dev/egommerce/identity-service/pkg/config"
	"github.com/go-pg/migrations/v8"
	"github.com/go-pg/pg/v10"
)

const (
	defAppName             = "identity-svc-migrations"
	defMigrationsTableName = "identity.migrations"
	defLoggerAddr          = "api-logger:24224"
	// defKVNmspc             = "dev.egommerce/service/identity-migration"
)

const usageText = `This program runs command on the db. Supported commands are:
  - init - creates version info table in the database
  - up - runs all available migrations.
  - up [target] - runs available migrations up to the target one.
  - down - reverts last migration.
  - reset - reverts all migrations.
  - version - prints current db version.
  - set_version [version] - sets db version without running migrations.
Usage:
  go run cmd/migrate/main.go <command> [args]
`

func main() {
	if config.ErrLoadingEnvs != nil {
		log.Panicln("Error loading .env file", config.ErrLoadingEnvs)
	}

	// dbURL := config.GetEnv("DATABASE_URL", defDbURL)
	loggerAddr := config.GetEnv("LOGGER_ADDR", defLoggerAddr)
	mTblName := config.GetEnv("MIGRATIONS_TABLE_NAME", defMigrationsTableName)

	logHost, logPort, _ := fluentd.ParseAddr(loggerAddr)
	logger, _ := fluentd.NewLogger(defAppName, logHost, logPort)
	defer logger.Close()

	flag.Usage = usage
	flag.Parse()

	db := pg.Connect(&pg.Options{ // FIXME
		Addr:     "postgres-db:5432",
		User:     "postgres",
		Password: "12345678",
		Database: "egommerce",
	})

	mig := migrations.NewCollection()
	mig.SetTableName(mTblName)
	err := mig.DiscoverSQLMigrations("./migrations")
	if err != nil {
		fmt.Println(err)
	}

	oldVersion, newVersion, err := mig.Run(db, flag.Args()...)
	if err != nil {
		exitf(err.Error())
	}
	if newVersion != oldVersion {
		fmt.Printf("migrated from version %d to %d\n", oldVersion, newVersion)
	} else {
		fmt.Printf("version is %d\n", oldVersion)
	}
}

func usage() {
	fmt.Print(usageText)
	flag.PrintDefaults()
	os.Exit(2)
}

func errorf(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, s+"\n", args...)
}

func exitf(s string, args ...interface{}) {
	errorf(s, args...)
	os.Exit(1)
}
