package contented

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

	"github.com/boltdb/bolt"
	"github.com/speps/go-hashids"
)

const (
	hashIdSalt      = "contented"
	hashIdMinLength = 2
)

type Metadata struct {
	FileHash   string
	FileSize   int64
	UploadTime time.Time
	UploadIP   string
	Filename   string
	MimeType   string
}

func (this *Server) Metadata(fileID string) (*Metadata, error) {
	var m Metadata
	err := this.db.View(func(tx *bolt.Tx) error {
		content := tx.Bucket(this.metadataBucket).Get([]byte(fileID))
		if len(content) == 0 {
			return os.ErrNotExist
		}

		return json.Unmarshal(content, &m)
	})
	if err != nil {
		return nil, err
	}

	return &m, nil
}

func idToString(v uint64) string {
	hd := hashids.NewData()
	hd.Salt = hashIdSalt
	hd.MinLength = hashIdMinLength
	h := hashids.NewWithData(hd)
	s, _ := h.EncodeInt64([]int64{int64(v)})
	return s
}

func (this *Server) AddMetadata(m Metadata) (string, error) {
	jb, err := json.Marshal(m)
	if err != nil {
		return "", err
	}

	var shortRef string = ""

	err = this.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket(this.metadataBucket)
		seq, _ := b.NextSequence() // cannot fail
		shortRef = idToString(seq)
		return tx.Bucket(this.metadataBucket).Put([]byte(shortRef), jb)
	})
	if err != nil {
		return "", err
	}
	if shortRef == "" {
		return "", errors.New("Invalid URL generated")
	}

	return shortRef, nil
}

func (this *Server) handleInformation(w http.ResponseWriter, fileID string) {
	m, err := this.Metadata(fileID)
	if err != nil {
		if os.IsNotExist(err) {
			http.Error(w, "Not found", 404)
			return
		}

		log.Println(err.Error())
		http.Error(w, "Internal error", 500)
		return
	}

	this.serveJsonObject(w, m)
}
