package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"sync"
)

var backends = []string{
	"http://backend1.local/api",
	"http://backend2.local/api",
	"http://backend3.local/api",
}

func forwardRequestToBackend(wg *sync.WaitGroup, client *http.Client, backend string, req *http.Request, responses chan<- string) {
	defer wg.Done()

	// Recréer la requête HTTP
	forwardReq, err := http.NewRequest(req.Method, backend, req.Body)
	if err != nil {
		log.Printf("Error creating request for %s: %v", backend, err)
		responses <- fmt.Sprintf("Error: %v", err)
		return
	}

	// Copier les en-têtes de la requête originale
	forwardReq.Header = req.Header.Clone()

	// Envoyer la requête au backend
	resp, err := client.Do(forwardReq)
	if err != nil {
		log.Printf("Error forwarding to %s: %v", backend, err)
		responses <- fmt.Sprintf("Error: %v", err)
		return
	}
	defer resp.Body.Close()

	// Lire la réponse du backend
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Printf("Error reading response from %s: %v", backend, err)
		responses <- fmt.Sprintf("Error: %v", err)
		return
	}

	// Ajouter la réponse dans le canal
	responses <- fmt.Sprintf("Response from %s: %s", backend, body)
}

func handler(w http.ResponseWriter, req *http.Request) {
	client := &http.Client{}
	var wg sync.WaitGroup
	responses := make(chan string, len(backends))

	// Forward la requête vers chaque backend
	for _, backend := range backends {
		wg.Add(1)
		go forwardRequestToBackend(&wg, client, backend, req, responses)
	}

	// Attendre la fin de toutes les requêtes
	wg.Wait()
	close(responses)

	// Collecter et afficher les réponses des backends
	for response := range responses {
		fmt.Fprintf(w, "%s\n", response)
	}
}

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("Starting server on :8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalf("Server failed: %v", err)
	}
}
