// This file was originally part of the project "LURE - Linux User REpository", created by Elara Musayelyan.
// It has been modified as part of "ALR - Any Linux Repository" by Евгений Храмов.
//
// ALR - Any Linux Repository
// Copyright (C) 2025 Евгений Храмов
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package main

import (
	"context"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"github.com/mattn/go-isatty"
	"github.com/urfave/cli/v2"

	oldLogger "go.elara.ws/logger"

	"gitea.plemya-x.ru/Plemya-x/ALR/internal/config"
	"gitea.plemya-x.ru/Plemya-x/ALR/internal/db"
	"gitea.plemya-x.ru/Plemya-x/ALR/internal/translations"
	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/loggerctx"
	"gitea.plemya-x.ru/Plemya-x/ALR/pkg/manager"

	"gitea.plemya-x.ru/Plemya-x/ALR/internal/logger"
)

var versionCmd = &cli.Command{
	Name:  "version",
	Usage: "Print the current ALR version and exit",
	Action: func(ctx *cli.Context) error {
		println(config.Version)
		return nil
	},
}

func GetApp() *cli.App {
	return &cli.App{
		Name:  "alr",
		Usage: "Any Linux Repository",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:    "pm-args",
				Aliases: []string{"P"},
				Usage:   "Arguments to be passed on to the package manager",
			},
			&cli.BoolFlag{
				Name:    "interactive",
				Aliases: []string{"i"},
				Value:   isatty.IsTerminal(os.Stdin.Fd()),
				Usage:   "Enable interactive questions and prompts",
			},
		},
		Commands: []*cli.Command{
			installCmd,
			removeCmd,
			upgradeCmd,
			GetInfoCmd(),
			listCmd,
			buildCmd,
			addrepoCmd,
			removerepoCmd,
			refreshCmd,
			fixCmd,
			genCmd,
			helperCmd,
			versionCmd,
		},
		Before: func(c *cli.Context) error {
			ctx := c.Context
			log := loggerctx.From(ctx)

			cmd := c.Args().First()
			if cmd != "helper" && !config.Config(ctx).Unsafe.AllowRunAsRoot && os.Geteuid() == 0 {
				log.Fatal("Running ALR as root is forbidden as it may cause catastrophic damage to your system").Send()
			}

			if trimmed := strings.TrimSpace(c.String("pm-args")); trimmed != "" {
				args := strings.Split(trimmed, " ")
				manager.Args = append(manager.Args, args...)
			}

			return nil
		},
		After: func(ctx *cli.Context) error {
			return db.Close()
		},
		EnableBashCompletion: true,
	}
}

func main() {
	translations.Setup()
	logger.SetupDefault()

	app := GetApp()

	ctx := context.Background()
	log := translations.NewLogger(ctx, oldLogger.NewCLI(os.Stderr), config.Language(ctx))
	ctx = loggerctx.With(ctx, log)

	// Set the root command to the one set in the ALR config
	manager.DefaultRootCmd = config.Config(ctx).RootCmd

	ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
	defer cancel()

	err := app.RunContext(ctx, os.Args)
	if err != nil {
		log.Error("Error while running app").Err(err).Send()
	}
}