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() {
	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))
}
