package main

import (
	"log"
	"net/http"
	"os"
)

type HtmlDir struct {
	dir http.Dir
}

func (dir HtmlDir) Open(name string) (http.File, error) {
	file, err := dir.dir.Open(name)
	if os.IsNotExist(err) {
		file, err = dir.dir.Open(name + ".html")
	}

	return file, err
}

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	frontendPath := os.Getenv("FRONTEND_PATH")
	if frontendPath == "" {
		frontendPath = "static"
	}

	dbPath := os.Getenv("DB_PATH")
	if dbPath == "" {
		dbPath = "./database.sqlite"
	}

	db, err := NewDatabase(dbPath, os.Getenv("ROOT_PASSWORD"))
	if err != nil {
		log.Fatal(err.Error())
	}
	defer db.Close()

	apiHandler := MakeApiHandler(db)

	mux := http.NewServeMux()
	mux.Handle("/", http.FileServer(HtmlDir{http.Dir(frontendPath)}))
	mux.Handle("GET /api/blog", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogGet(writer, request)
	}), false))
	mux.Handle("PUT /api/blog", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogPut(writer, request)
	}), true))
	mux.Handle("GET /api/blog/{id}", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogGetSingle(writer, request)
	}), false))
	mux.Handle("PATCH /api/blog/{id}", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogPatch(writer, request)
	}), true))
	mux.Handle("DELETE /api/blog/{id}", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogDelete(writer, request)
	}), true))
	mux.Handle("GET /api/blog/{articleId}/file/{fileId}", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogFileGetSingle(writer, request)
	}), false))
	mux.Handle("POST /api/blog/{id}/publish", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogPostPublish(writer, request)
	}), true))
	mux.Handle("POST /api/blog/{id}/unpublish", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogPostUnpublish(writer, request)
	}), true))
	mux.Handle("GET /api/blog/tags", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeBlogTagsGet(writer, request)
	}), false))
	mux.HandleFunc("POST /api/login", func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeLoginPost(writer, request)
	})
	mux.Handle("POST /api/logout", apiHandler.ProcessAuth(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		apiHandler.ServeLogoutPost(writer, request)
	}), true))
	mux.HandleFunc("/api/", func(writer http.ResponseWriter, request *http.Request) {
		http.NotFound(writer, request)
	})

	log.Println("Listening on port", port)
	err = http.ListenAndServe(":"+port, mux)
	if err != nil {
		log.Fatalln(err.Error())
	}
}
