package main

import (
	"encoding/json"
	"log"
	"net"
	"net/http"
	"os"
	"strings"
	"time"

	// "git.mmnx.de/Moe/webOffice_backend/contacts"
	// "git.mmnx.de/Moe/webOffice_backend/module"
	"git.mmnx.de/mmnx/cdn/module"
	"git.mmnx.de/mmnx/cdn/files"
	
	"github.com/gorilla/mux"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"github.com/rs/cors"
	"github.com/urfave/negroni"
)

func connectDB(host string) *gorm.DB {
	time.Sleep(250 * time.Millisecond) // let mysql startup
	db, err := gorm.Open("mysql", "root:root@tcp("+host+")/cdn?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		if strings.HasPrefix(err.Error(), "default addr for network") {
			log.Println("Reconnecting..")
			return connectDB(host)
		}

		log.Println(err)
		return nil
	}

	log.Println("Apparently connected")
	return db
}

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile) // get line numberz

	c := cors.New(cors.Options{ // allow ng dev server access
		AllowedOrigins: []string{"http://localhost:4200"},
		AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
	})

	// lookup docker db ip
	names, err := net.LookupHost("cdn-db")
	if err != nil {
		log.Println("Failed to get DB host: ", err)
		return // TODO retry
	}

	if len(names) < 1 {
		log.Println("No hosts")
		return
	}

	db := connectDB(names[0])
	defer db.Close()

	router := mux.NewRouter()
	apiV1 := router.PathPrefix("/api/v1").Subrouter()

	modConf := module.Config{apiV1, "/api/v1", db, true, log.New(os.Stdout, "[debug] ", log.LstdFlags|log.Lshortfile)} // debug
	//modConf := module.Config{apiV1, "/api/v1", db, false, log.New(os.Stdout, "[log] ", log.LstdFlags|log.Lshortfile)} // production
	module.Conf = modConf

	// contacts.RegisterModule(&modConf)
	files.RegisterModule(&modConf)

	module.NegroniRoute(apiV1, "/api/v1", "/test", "GET", HandlerFunc, AuthFunc)

	n := negroni.Classic()
	n.Use(module.NewHTTPStatusHandler())
	n.Use(c)
	n.UseHandler(router)
	n.Run(":3000")

}

// AuthFunc ...
func AuthFunc(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
	// TODO some kind of auth

	next(w, r)
}

// HandlerFunc ...
func HandlerFunc(w http.ResponseWriter, r *http.Request) {
	encJSON, _ := json.Marshal("wörks") // err
	// errs.HandleError(errs.ErrEncodingJSON, err)
	//
	// // Error handling debug
	// err = errors.New("ayyyyy")
	// errs.HandleError(errs.ErrUnknown, err)

	// names, err := net.LookupHost("weboffice-db")
	// module.HandleError(module.ErrUnknown, err)
	//
	// spew.Dump(names)

	w.Write(encJSON)
	// log.Println(string(encJSON))
}