package main

/*
 * This file is part of Autogits.
 *
 * Copyright © 2024 SUSE LLC
 *
 * Autogits 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 2 of the License, or (at your option) any later
 * version.
 *
 * Autogits 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
 * Foobar. If not, see <https://www.gnu.org/licenses/>.
 */

import (
	"flag"
	"log"
	"net/url"
	"slices"
	"time"

	"src.opensuse.org/autogits/common"
	"src.opensuse.org/autogits/common/gitea-generated/models"
)

const (
	AppName   = "workflow-pr"
	GitAuthor = "AutoGits - pr-review"
	GitEmail  = "adam+autogits-pr@zombino.com"
)

/*
func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error {
	// clone PR head and base and return path
	if h.HasError() {
		return h.Error
	}
	if _, err := os.Stat(path.Join(h.GitPath, pr.Head.Sha)); os.IsNotExist(err) {
		h.GitExec("", "clone", "--depth", "1", pr.Head.Repo.CloneURL, pr.Head.Sha)
		h.GitExec(pr.Head.Sha, "fetch", "--depth", "1", "origin", pr.Head.Sha, pr.Base.Sha)
	} else if err != nil {
		h.Error = err
	}

	return h.Error
}*/

var DebugMode bool
var ListPROnly bool
var PRID int64
var CurrentUser *models.User

func main() {
	if err := common.RequireGiteaSecretToken(); err != nil {
		log.Fatal(err)
	}
	if err := common.RequireRabbitSecrets(); err != nil {
		log.Fatal(err)
	}

	workflowConfig := flag.String("config", "", "Repository and workflow definition file")
	giteaUrl := flag.String("gitea-url", "https://src.opensuse.org", "Gitea instance")
	rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance")
	flag.BoolVar(&DebugMode, "debug", false, "Extra debugging information")
	checkOnStart := flag.Bool("check-on-start", false, "Check all repositories for consistency on start, without delays")
	checkIntervalHours := flag.Float64("check-interval", 5, "Check interval (+-random delay) for repositories for consitency, in hours")
	flag.BoolVar(&ListPROnly, "list-prs-only", false, "Only lists PRs without acting on them")
	flag.Int64Var(&PRID, "id", -1, "Process only the specific ID and ignore the rest. Use for debugging")

	flag.Parse()

	if len(*workflowConfig) == 0 {
		log.Fatalln("No configuratio file specified. Aborting")
	}

	gitea := common.AllocateGiteaTransport(*giteaUrl)
	config, err := common.ReadConfigFile(*workflowConfig)
	if err != nil {
		log.Fatal(err)
	}

	configs, err := common.ResolveWorkflowConfigs(gitea, config) 
	if err != nil {
		log.Fatal(err)
	}

	req := new(RequestProcessor)

	req.configuredRepos = make(map[string][]*common.AutogitConfig)
	req.git = &common.GitHandlerGeneratorImpl{}
	orgs := make([]string, 0, 1)
	for _, c := range configs {
		if slices.Contains(c.Workflows, "pr") {
			if DebugMode {
				log.Printf("  + adding org: '%s', branch: '%s', prjgit: '%s'\n", c.Organization, c.Branch, c.GitProjectName)
			}
			configs := req.configuredRepos[c.Organization]
			if configs == nil {
				configs = make([]*common.AutogitConfig, 0, 1)
			}
			configs = append(configs, c)
			req.configuredRepos[c.Organization] = configs

			orgs = append(orgs, c.Organization)
		}
	}

	if CurrentUser, err = gitea.GetCurrentUser(); err != nil {
		log.Fatal(err)
	}
	log.Println("Running with token from", CurrentUser.UserName)

	req.Synced = &PullRequestSynced{
		gitea: gitea,
	}
	req.Opened = &PullRequestOpened{
		gitea: gitea,
	}
	req.Closed = &PullRequestClosed{
		gitea: gitea,
	}
	req.Review = &PullRequestReviewed{
		gitea: gitea,
	}

	checker := CreateDefaultStateChecker(*checkOnStart, req, gitea, time.Duration(*checkIntervalHours)*time.Hour)
	go checker.ConsistencyCheckProcess()

	var defs common.ListenDefinitions

	defs.GitAuthor = GitAuthor
	defs.RabbitURL, _ = url.Parse(*rabbitUrl)

	defs.Handlers = make(map[string]common.RequestProcessor)
	defs.Handlers[common.RequestType_PR] = req
	defs.Handlers[common.RequestType_PRSync] = req
	defs.Handlers[common.RequestType_PRReviewAccepted] = req
	defs.Handlers[common.RequestType_PRReviewRejected] = req

	log.Fatal(defs.ProcessRabbitMQEvents())
}
