// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
// SPDX-License-Identifier: GPL-3.0-or-later

package security

import (
	"context"

	repo_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/repo"
	security_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/security"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/git"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/log"
)

// ScanOnPush runs enabled scanners against a commit pushed to the default branch.
// Called from services/repository/push.go on default branch pushes.
func ScanOnPush(ctx context.Context, repo *repo_model.Repository, commit *git.Commit) {
	if commit == nil {
		return
	}

	cfg, err := security_model.GetScannerConfig(ctx, repo.ID)
	if err != nil {
		log.Error("SecurityScan: GetScannerConfig for %s: %v", repo.FullName(), err)
		return
	}
	if !cfg.Enabled {
		return
	}

	var scanners []Scanner
	if cfg.SecretScanner {
		scanners = append(scanners, NewSecretScanner())
	}
	if cfg.DependScanner {
		scanners = append(scanners, NewDependencyScanner())
	}
	// Future scanners added here:
	// if cfg.CodeScanner { scanners = append(scanners, NewCodeScanner()) }

	if len(scanners) == 0 {
		return
	}

	totalFindings := 0
	for _, s := range scanners {
		findings, err := s.ScanTree(commit)
		if err != nil {
			log.Error("SecurityScan: %s scanner for %s: %v", s.Type(), repo.FullName(), err)
			continue
		}

		for _, f := range findings {
			alert := &security_model.SecurityAlert{
				RepoID:      repo.ID,
				Scanner:     f.Scanner,
				Severity:    f.Severity,
				RuleID:      f.RuleID,
				Title:       f.Title,
				Description: f.Description,
				FilePath:    f.FilePath,
				LineNumber:  f.LineNumber,
				CommitSHA:   f.CommitSHA,
				Fingerprint: f.Fingerprint,
				Metadata:    f.Metadata,
			}
			if err := security_model.CreateOrUpdateAlert(ctx, alert); err != nil {
				log.Error("SecurityScan: CreateOrUpdateAlert: %v", err)
			}
			totalFindings++
		}
	}

	if totalFindings > 0 {
		log.Warn("SecurityScan: %d findings in %s", totalFindings, repo.FullName())
	}
}
