package store

import (
	
	

	bolt 
)

// Parameters for directory history scores.
const (
	DirScoreDecay     = 0.986 // roughly 0.5^(1/50)
	DirScoreIncrement = 10
	DirScorePrecision = 6
)

func () {
	initDB["initialize directory history table"] = func( *bolt.Tx) error {
		,  := .CreateBucketIfNotExists([]byte(bucketDir))
		return 
	}
}

func ( float64) []byte {
	return []byte(strconv.FormatFloat(, 'E', DirScorePrecision, 64))
}

func ( []byte) float64 {
	,  := strconv.ParseFloat(string(), 64)
	return 
}

// AddDir adds a directory to the directory history.
func ( *dbStore) ( string,  float64) error {
	return .db.Update(func( *bolt.Tx) error {
		 := .Bucket([]byte(bucketDir))

		 := .Cursor()
		for ,  := .First();  != nil; ,  = .Next() {
			 := unmarshalScore() * DirScoreDecay
			.Put(, marshalScore())
		}

		 := []byte()
		 := float64(0)
		if  := .Get();  != nil {
			 = unmarshalScore()
		}
		 += DirScoreIncrement * 
		return .Put(, marshalScore())
	})
}

// AddDir adds a directory and its score to history.
func ( *dbStore) ( string,  float64) error {
	return .db.Update(func( *bolt.Tx) error {
		 := .Bucket([]byte(bucketDir))
		return .Put([]byte(), marshalScore())
	})
}

// DelDir deletes a directory record from history.
func ( *dbStore) ( string) error {
	return .db.Update(func( *bolt.Tx) error {
		 := .Bucket([]byte(bucketDir))
		return .Delete([]byte())
	})
}

// Dirs lists all directories in the directory history whose names are not
// in the blacklist. The results are ordered by scores in descending order.
func ( *dbStore) ( map[string]struct{}) ([]Dir, error) {
	var  []Dir

	 := .db.View(func( *bolt.Tx) error {
		 := .Bucket([]byte(bucketDir))
		 := .Cursor()
		for ,  := .First();  != nil; ,  = .Next() {
			 := string()
			if ,  := [];  {
				continue
			}
			 = append(, Dir{
				Path:  ,
				Score: unmarshalScore(),
			})
		}
		sort.Sort(sort.Reverse(dirList()))
		return nil
	})
	return , 
}

type dirList []Dir

func ( dirList) () int {
	return len()
}

func ( dirList) (,  int) bool {
	return [].Score < [].Score
}

func ( dirList) (,  int) {
	[], [] = [], []
}