package main

import (
	"database/sql"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"

	"git.rpuzonas.com/rpuzonas/go-rss-aggregator/internal/database"
	"github.com/go-chi/chi"
	"github.com/go-chi/cors"
	"github.com/joho/godotenv"
	_ "github.com/mattn/go-sqlite3"
)

type apiConfig struct {
	DB *database.Queries
}

func assert_getenv(name string) string {
	value := os.Getenv(name)
	if value == "" {
		log.Output(2, fmt.Sprintf("missing %s environment variable", name))
		os.Exit(1)
	}
	return value
}

func createV1Router(cfg *apiConfig) chi.Router {
	v1Router := chi.NewRouter();

	v1Router.Get("/healthz", handlerReadiness)
	v1Router.Get("/err", handleErr)

	v1Router.Post("/user", cfg.handlerCreateUser)
	v1Router.Get("/user", cfg.middlewareAuth(cfg.handlerGetUser))
	v1Router.Get("/user/feeds", cfg.middlewareAuth(cfg.handlerGetCreatedFeeds))

	v1Router.Post("/feeds", cfg.middlewareAuth(cfg.handlerCreateFeed))
	v1Router.Get("/feeds", cfg.handlerGetAllFeeds)

	v1Router.Post("/feed-follows", cfg.middlewareAuth(cfg.handlerFollowFeed))
	v1Router.Delete("/feed-follows/{feedFollowID}", cfg.middlewareAuth(cfg.handlerDeleteFeedFollow))
	v1Router.Get("/feed-follows", cfg.middlewareAuth(cfg.handlerGetFeedFollows))

	return v1Router
}

func main() {
	godotenv.Load(".env")

	portStr := assert_getenv("PORT")
	db_url := assert_getenv("DB_URL")

	conn, err := sql.Open("sqlite3", db_url)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	db := database.New(conn)
	apiCfg := apiConfig{ DB: db }

	router := chi.NewRouter()
	router.Use(cors.Handler(cors.Options{
		AllowedOrigins: []string{"https://*", "http://*"},
		AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
		AllowedHeaders: []string{"*"},
		ExposedHeaders: []string{"Link"},
		AllowCredentials: false,
		MaxAge: 300,
	}))

	router.Mount("/v1", createV1Router(&apiCfg))

	srv := &http.Server{
		Handler: router,
		Addr: ":" + portStr,
	};

	go startScraping(db, 10, time.Minute)

	fmt.Printf("Listening on port: %s\n", portStr)
	err = srv.ListenAndServe();
	if err != nil {
		log.Fatal(err)
	}
}
