package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"strings"
	"sync"
	"time"

	"golang.org/x/sync/semaphore"
)

func main() {
	args := os.Args[1:]
	// Args might be a single string with line returns to delimit sites, break them apart
	if len(args) == 1 {
		args = strings.Split(args[0], "\n")
	}

	// Create a context with timeout for the entire operation
	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	wg := &sync.WaitGroup{}
	wg.Add(len(args))

	// Create a semaphore to limit concurrent requests to 30
	sem := semaphore.NewWeighted(30)

	now := time.Now()

	for _, a := range args {
		go get(ctx, a, wg, sem)
	}

	wg.Wait()

	fmt.Printf("It took %s for the entire process to finish\n", time.Since(now))
}

func get(ctx context.Context, s string, wg *sync.WaitGroup, sem *semaphore.Weighted) {
	defer wg.Done()

	// Acquire semaphore
	if err := sem.Acquire(ctx, 1); err != nil {
		log.Printf("failed to acquire semaphore for %s: %s\n", s, err)
		return
	}
	defer sem.Release(1)

	now := time.Now()

	_, err := http.Get(s)
	if err != nil {
		log.Printf("failed to retrieve %s: %s\n", s, err)
		return
	}
	log.Printf("Retrieved site %s in %s\n", s, time.Since(now))
}
