// This file is part of taldir, the Taler Directory implementation.
// Copyright (C) 2025 Martin Schanzenbach
//
// Taldir is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// Taldir is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: AGPL3.0-or-later

package main

import (
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"path"
	"path/filepath"
	"strings"

	_ "github.com/lib/pq"
	talerutil "github.com/schanzen/taler-go/pkg/util"
	"rsc.io/getopt"

	"gopkg.in/ini.v1"
)

var (
	version        string
	taldirdatahome string
	taldirconfdir  string
)

func printHelp() {
	fmt.Print("taler-directory-dbinit\n\n")
	getopt.PrintDefaults()
	fmt.Print("\nReport bugs to gnunet-developers@gnu.org.\n",
		"Home page: https://taler.net\n",
		"General help using GNU software: http://www.gnu.org/gethelp/\n")
}

func printKey(key *ini.Key, onlyValue bool) {
	if onlyValue {
		fmt.Printf("%s\n", key.String())
		return
	}
	fmt.Printf("%s = %s\n", key.Name(), key.String())
}

func printCfgOptions(sec *ini.Section, option *string, onlyValue *bool) {
	if len(*option) == 0 {
		for _, key := range sec.Keys() {
			printKey(key, *onlyValue)
		}
		return
	}
	if !sec.HasKey(*option) {
		fmt.Printf("Section `%s' does not have option `%s'!\n", sec.Name(), *option)
		os.Exit(1)
	}
	key := sec.Key(*option)
	printKey(key, *onlyValue)
}

func printCfgSections(f *ini.File) {
	for _, sec := range f.Sections() {
		fmt.Println(sec.Name())
	}
}

func main() {
	var cfg *ini.File
	var err error
	var cfgFlag = flag.String("c", "", "Configuration file to use")
	getopt.Alias("c", "config")
	var helpFlag = flag.Bool("h", false, "Print help")
	getopt.Alias("h", "help")
	var versionFlag = flag.Bool("v", false, "Print version")
	getopt.Alias("v", "version")

	getopt.Parse()
	if *helpFlag {
		printHelp()
		return
	}
	if *versionFlag {
		fullName, err := os.Executable()
		if err != nil {
			log.Panic(err)
		}
		fmt.Printf("%s %s", filepath.Base(fullName), version)
		return
	}
	cfgfile := path.Join(taldirconfdir, "taldir.conf")
	if len(*cfgFlag) != 0 {
		cfg, err = ini.Load(*cfgFlag)
		if err != nil {
			fmt.Printf("Failed to read config: %v\n", err)
			os.Exit(1)
		}
	} else {
		// FIXME also try in datahome
		cfg, err = ini.LooseLoad(cfgfile)
		if err != nil {
			fmt.Printf("Failed to read config: %v\n", err)
			os.Exit(1)
		}
	}
	psqlconn := cfg.Section("taldir-pq").Key("connection_string").MustString("postgres:///taler-directory")
	segments := strings.Split(strings.Split(psqlconn, "?")[0], "/")
	dbName := segments[len(segments)-1]

	db, err := sql.Open("postgres", psqlconn)
	if err != nil {
		log.Panic(err)
	}
	defer db.Close()
	err = talerutil.DBInit(db, taldirdatahome, dbName, "taler-directory")
	if err != nil {
		log.Fatalf("%v\n", err)
	}
}
