package main

import (
	"compress/gzip"
	"encoding/csv"
	"encoding/json"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"

	badger "github.com/dgraph-io/badger/v3"
	"github.com/gin-gonic/gin"
	"github.com/joho/godotenv"
	"github.com/mattn/go-jsonpointer"
)

var db *badger.DB

func CheckSaleUrl(c *gin.Context) {

	corpusID := c.Param("corpus_id")
	docID := c.Param("doc_id")
	textID := c.Param("text_id")

	err := db.View(func(txn *badger.Txn) error {

		item, err := txn.Get([]byte(corpusID + "/" + docID + "/" + textID))

		if err != nil {
			c.String(http.StatusNotFound, "No entry found")
			return nil
		}

		err = item.Value(func(v []byte) error {
			c.String(http.StatusOK, string(v))
			return nil
		})

		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		c.String(http.StatusNotFound, err.Error())
	}
}

func add(dbx *badger.DB, corpusID, docID, textID string, provider string, url string) error {
	err := dbx.Update(func(txn *badger.Txn) error {
		err := txn.Set([]byte(corpusID+"/"+docID+"/"+textID), []byte(provider+","+url))
		return err
	})
	return err
}

func InitDB(dir string) {
	if db != nil {
		return
	}
	db = initDB(dir)
}

func initDB(dir string) *badger.DB {
	dbx, err := badger.Open(badger.DefaultOptions(dir))
	if err != nil {
		log.Fatal(err)
	}
	return dbx
}

func closeDB() {
	db.Close()
}

func IndexDB(ri io.Reader) error {
	return indexDB(ri, db)
}

// indexDB reads in a csv file and adds
// information to the database
func indexDB(ri io.Reader, dbx *badger.DB) error {

	r := csv.NewReader(ri)

	txn := dbx.NewTransaction(true)

	i := 0

	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		if err := txn.Set([]byte(record[0]), []byte(record[1]+","+record[2])); err == badger.ErrTxnTooBig {
			log.Println("Commit", record[0], "after", i, "inserts")
			i = 0
			err = txn.Commit()
			if err != nil {
				log.Fatal("Unable to commit")
			}
			txn = db.NewTransaction(true)
			_ = txn.Set([]byte(record[0]), []byte(record[1]+","+record[2]))
		}
		i++
	}
	return txn.Commit()
}

func setupRouter() *gin.Engine {
	r := gin.Default()
	r.LoadHTMLGlob("templates/*")

	korapServer := os.Getenv("KORAP_SERVER")
	if korapServer == "" {
		korapServer = "https://korap.ids-mannheim.de"
	}

	var pluginManifest map[string]any
	json.Unmarshal([]byte(`{
		"name" : "External Resources",
		"desc" : "Retrieve content from an external provider",
		"embed" : [{
			"panel" : "match",
			"title" : "Full Text",
			"classes" : ["plugin", "cart"],
			"icon" : "\f07a",
			"onClick" : {
				"action" : "addWidget",
				"template":"",
				"permissions": [
					"scripts",
					"popups" 
				]
			}
		}]
	}`), &pluginManifest)

	externalResources := os.Getenv("KORAP_EXTERNAL_RESOURCES")
	if externalResources == "" {
		externalResources = "https://korap.ids-mannheim.de/plugin/external/"
	}
	jsonpointer.Set(pluginManifest, "/embed/0/onClick/template", externalResources)

	r.Use(func() gin.HandlerFunc {
		return func(c *gin.Context) {
			h := c.Writer.Header()
			h.Set("Access-Control-Allow-Origin", "null")
			h.Set("Access-Control-Allow-Credentials", "null")
			h.Set("Vary", "Origin")
		}
	}(),
	)

	// Return widget page
	r.GET("/", func(c *gin.Context) {
		c.HTML(http.StatusOK, "main.html", gin.H{
			"korapServer": korapServer,
		})
	})

	// Return resource information
	r.HEAD("/:corpus_id/:doc_id/:text_id", CheckSaleUrl)
	r.GET("/:corpus_id/:doc_id/:text_id", CheckSaleUrl)

	// Return plugin manifest
	r.GET("/plugin.json", func(c *gin.Context) {
		c.JSON(200, pluginManifest)
	})

	return r
}

func main() {
	gin.SetMode(gin.ReleaseMode)

	if godotenv.Load() != nil {
		log.Println(".env file not loaded.")
	}

	InitDB("db")
	defer closeDB()

	// Index csv file
	if len(os.Args) > 1 {

		file, err := os.Open(os.Args[1])
		if err != nil {
			log.Fatal(err)
		}

		fileExt := filepath.Ext(os.Args[1])

		if fileExt == ".gz" || fileExt == ".csvz" {
			var gzipr io.Reader
			gzipr, err = gzip.NewReader(file)
			if err != nil {
				log.Fatal("Unable to open gzip file")
			} else {
				err = IndexDB(gzipr)
			}
		} else {
			err = IndexDB(file)
		}

		if err != nil {
			log.Fatal("Unable to commit")
		}
	}
	r := setupRouter()

	port := os.Getenv("KORAP_EXTERNAL_RESOURCES_PORT")
	if port == "" {
		port = "5722"
	}

	log.Fatal(http.ListenAndServe(":"+port, r))
}
