package git

import (
	"fmt"
	"net/url"
	"path/filepath"
	"strings"

	"bit.admedia.com/scm/ad/adpilot-indexing-repo-sync.com/internal/config"
)

// CloneURL builds a Bitbucket Server clone URL without embedded credentials.
func CloneURL(baseURL, repoID string) (string, error) {
	if err := ValidateRepoID(repoID); err != nil {
		return "", err
	}

	parts := strings.Split(repoID, "/")
	// repo_id is provider-qualified, e.g. "bitbucket_server:AD/slug". The
	// Bitbucket clone path wants the bare project ("ad"), not the provider
	// prefix. Strip everything up to and including the provider separator ':'
	// so we build /scm/ad/slug.git and not /scm/bitbucket_server:ad/slug.git
	// (the malformed URL that made force-sync fail with "Repository not found").
	projectSegment := parts[0]
	if idx := strings.LastIndex(projectSegment, ":"); idx >= 0 {
		projectSegment = projectSegment[idx+1:]
	}
	project := strings.ToLower(projectSegment)
	slug := parts[1]

	base := strings.TrimRight(strings.TrimSpace(baseURL), "/")
	if base == "" {
		return "", fmt.Errorf("bitbucket base url is required")
	}

	clonePath := fmt.Sprintf("/scm/%s/%s.git", project, slug)
	return joinURL(base, clonePath)
}

func joinURL(base, path string) (string, error) {
	u, err := url.Parse(base)
	if err != nil {
		return "", fmt.Errorf("parse bitbucket base url: %w", err)
	}
	u.Path = strings.TrimSuffix(u.Path, "/") + path
	u.RawQuery = ""
	u.Fragment = ""
	return u.String(), nil
}

// WorkspaceDirName returns the sanitized directory name for a repository clone.
func WorkspaceDirName(repoID string) string {
	dirName := strings.ReplaceAll(repoID, "/", "__")
	return strings.ReplaceAll(dirName, ":", "__")
}

// WorkspaceDir returns the sanitized local path for a repository clone.
func WorkspaceDir(cfg config.Config, repoID string) (string, error) {
	if err := ValidateRepoID(repoID); err != nil {
		return "", err
	}
	dirName := WorkspaceDirName(repoID)
	return filepath.Join(cfg.Git.WorkspacePath, dirName), nil
}
