package loganalyzer

import (
	"bufio"
	"context"
	"os"
	"strings"
	"sync"
)

// LogResult holds the count of log messages grouped by level.
type LogResult struct {
	InfoCount    int
	WarningCount int
	ErrorCount   int
}

func parseFile(file string )( LogResult, error) {
	// Simulate parsing
	fileOpen , err := os.Open(file)
	if err!=nil{
		return LogResult{}, err
	}
	defer fileOpen.Close()

	result := LogResult{}

	scanner := bufio.NewScanner(fileOpen)

	for scanner.Scan(){
		line:= strings.ToLower(scanner.Text())

		if strings.Contains(line,"info"){
			result.InfoCount++
		} else if strings.Contains(line,"warning"){
			result.WarningCount++
		} else if strings.Contains(line,"error"){
			result.ErrorCount++
		}
	}

	if err :=scanner.Err(); err != nil{
		return LogResult{} , err
	}
	
	return result, nil
}
// AnalyzeLogs reads and parses the provided files concurrently.
// It counts lines containing "INFO", "WARNING", and "ERROR".
// If the ctx is cancelled or times out, the function should return immediately with ctx.Err().
func AnalyzeLogs(ctx context.Context, filePaths []string) (LogResult, error) {
	// TODO: Implement concurrent log analysis.
	//
	files := filePaths

	resultsChan := make(chan LogResult , len(filePaths))
	var wg sync.WaitGroup
	
	for _,file :=range files{
		wg.Add(1)
		go func(file string){
			defer wg.Done()
			res ,err := parseFile(file)
			if err != nil{
				resultsChan <- LogResult{}
			}else{
				resultsChan <- res
			}
		}(file)
	}

	go func(){
		wg.Wait()
		close(resultsChan)
	}()
	total := LogResult{}
	// 3. Loop for each file and use select to handle context timeouts
	for i := 0; i < len(filePaths); i++ {
		select {
			case res, ok := <-resultsChan:
				if !ok {
					break
				}
				// 4. Aggregate the counts
				total.InfoCount += res.InfoCount
				total.WarningCount += res.WarningCount
				total.ErrorCount += res.ErrorCount
			case <-ctx.Done():
				// Exit immediately if the context is cancelled or timed out
				return LogResult{}, ctx.Err()
			}
		}
	return total, nil
	// Recommended Plan:
	// 1. Create a channel to receive results (or errors) from each file parsing goroutine.
	// 2. Spawn a goroutine for each file in filePaths.
	// 3. Inside each goroutine:
	//    - Open the file.
	//    - Read line-by-line (hint: use bufio.NewScanner).
	//    - For each line, check if it contains "INFO", "WARNING", or "ERROR" (hint: strings.Contains).
	//    - Crucially, check if the context is cancelled periodically or check ctx.Done() during work.
	//    - Send the file's LogResult back on the channel.
	// 4. In the main routine, collect results from the channel.
	//    - Use a select statement to either read a result from the channel or handle context cancellation:
	//      select {
	//      case res := <-resultsChan:
	//          // Add to running totals
	//      case <-ctx.Done():
	//          return LogResult{}, ctx.Err()
	//      }
	// 5. Aggregate and return the total LogResult.
	
}
