// This file is part of taler-mailbox, the Taler Mailbox implementation.
// Copyright (C) 2022 Martin Schanzenbach
//
// Taler-mailbox 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.
//
// Taler-mailbox 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 (
	"flag"
	"fmt"
	"gopkg.in/ini.v1"
	"gorm.io/driver/postgres"
	"log"
	"net/http"
	"os"
	"path"

	"github.com/schanzen/taler-go/pkg/merchant"
	"rsc.io/getopt"
	mailbox "taler.net/taler-mailbox/pkg/rest"
)

var (
	m               mailbox.Mailbox
	ltversion       string
	version         string
	mailboxdatahome string
	mailboxconfdir  string
	verbose         bool
)

func handleRequests(m *mailbox.Mailbox) {
	log.Fatal(http.ListenAndServe(m.Cfg.Ini.Section("mailbox").Key("bind_to").MustString("localhost:11000"), m.Router))
}

func printHelp() {
	fmt.Print("taler-mailbox\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 main() {
	var cfgFlag = flag.String("c", "mailbox.conf", "Configuration file to use")
	getopt.Alias("c", "config")
	// FIXME use flags
	loglevelStringOpt := flag.String("L", "INFO", "Log level to use. DEBUG, INFO, WARNING or ERROR")
	getopt.Alias("L", "loglevel")
	var verboseFlag = flag.Bool("v", false, "Verbose")
	getopt.Alias("v", "verbose")
	var helpFlag = flag.Bool("h", false, "Print help")
	getopt.Alias("h", "help")

	getopt.Parse()
	if *helpFlag {
		printHelp()
		return
	}
	cfgfile := path.Join(mailboxconfdir, "mailbox.conf")
	if len(*cfgFlag) != 0 {
		cfgfile = *cfgFlag
	}
	verbose = *verboseFlag
	loglevel := mailbox.LogInfo
	for loglevelNum, loglevelString := range mailbox.LoglevelStringMap {
		if loglevelString == *loglevelStringOpt {
			loglevel = loglevelNum
		}
	}
	m := mailbox.Mailbox{}
	iniCfg, err := ini.Load(cfgfile)
	if err != nil {
		log.Printf("Failed to read config: %v", err)
		os.Exit(1)
	}
	psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
		iniCfg.Section("mailbox-pq").Key("host").MustString("localhost"),
		iniCfg.Section("mailbox-pq").Key("port").MustInt64(5432),
		iniCfg.Section("mailbox-pq").Key("user").MustString("taler-mailbox"),
		iniCfg.Section("mailbox-pq").Key("password").MustString("secret"),
		iniCfg.Section("mailbox-pq").Key("db_name").MustString("taler-mailbox"))
	db := postgres.Open(psqlconn)
	merchURL := iniCfg.Section("mailbox").Key("merchant_baseurl_private").MustString("http://merchant.mailbox/instances/myInstance")
	merchToken := iniCfg.Section("mailbox").Key("merchant_token").MustString("secretAccessToken")
	merch := merchant.NewMerchant(merchURL, merchToken)
	m.Initialize(mailbox.MailboxConfig{
		LibtoolVersion: ltversion,
		Version:        version,
		Datahome:       mailboxdatahome,
		DB:             db,
		Ini:            iniCfg,
		Merchant:       merch,
		Loglevel:       loglevel,
	})
	handleRequests(&m)
}
