package utils import ( "crypto/rand" "encoding/hex" "fmt" "net/url" "os" "path/filepath" "strings" "time" ) // GenerateID creates a unique identifier func GenerateID() string { b := make([]byte, 8) rand.Read(b) return hex.EncodeToString(b) } // Now returns current time func Now() time.Time { return time.Now() } // IsValidGitHubURL validates if a URL is a valid GitHub repository URL func IsValidGitHubURL(u string) bool { parsed, err := url.Parse(u) if err != nil { return false } if parsed.Host != "github.com" && parsed.Host != "www.github.com" { return false } parts := strings.Split(strings.Trim(parsed.Path, "/"), "/") return len(parts) >= 2 } // SaveResult stores analysis result and diagram (in-memory for now) func SaveResult(id string, diagram interface{}) { // In production, store in database or cache // For now, we'll use a simple in-memory map getDiagramStore()[id] = diagram } // GetDiagram retrieves a diagram by ID func GetDiagram(id string) interface{} { store := getDiagramStore() if diagram, ok := store[id]; ok { return diagram } return nil } // GetStatus retrieves analysis status (simplified) func GetStatus(id string) map[string]interface{} { // In production, this would fetch from database diagram := GetDiagram(id) if diagram == nil { return nil } return map[string]interface{}{ "id": id, "status": "completed", } } // In-memory storage (for development only) var diagramStore = make(map[string]interface{}) func getDiagramStore() map[string]interface{} { return diagramStore } // CountLines counts lines in a directory (simplified) func CountLines(dir string) int { total := 0 filepath.WalkDir(dir, func(path string, d os.DirEntry, err error) error { if err != nil || d.IsDir() { return nil } // Skip binary files and certain extensions ext := strings.ToLower(filepath.Ext(path)) skipExts := map[string]bool{ ".png": true, ".jpg": true, ".jpeg": true, ".gif": true, ".pdf": true, ".zip": true, ".tar": true, ".gz": true, } if skipExts[ext] { return nil } data, err := os.ReadFile(path) if err != nil { return nil } lines := strings.Count(string(data), "\n") if len(data) > 0 && !strings.HasSuffix(string(data), "\n") { lines++ } total += lines return nil }) return total } // CountDirectories counts directories in a structure func CountDirectories(root models.RepositoryStructure) int { count := 0 var walk func(models.RepositoryStructure) walk = func(node models.RepositoryStructure) { if node.Type == "directory" { count++ } for _, child := range node.Children { walk(child) } } walk(root) return count } // RunCommand executes a shell command (placeholder) func RunCommand(command string) error { // In production, use exec.Command return fmt.Errorf("not implemented") } // Models reference (to avoid circular import) type RepositoryStructure struct { Name string Type string Path string Children []RepositoryStructure }