package main

import (
	"crypto/rand"
	"encoding/hex"
	"errors"
	"fmt"
	"time"

	"code.ivysaur.me/trpcd/DataSource"
)

var ErrNotImplemented error = errors.New("Not implemented")

type sampleDataSession struct {
	torrents      []DataSource.Torrent
	updateCounter int64
}

func fakeTorrent(id int64, name string) DataSource.Torrent {

	// Invent a random hashString
	hashBytes := make([]byte, 40)
	n, err := rand.Read(hashBytes)
	if err != nil {
		panic(err)
	}
	if n != len(hashBytes) {
		panic("Crypto primitive failure")
	}
	hashString := hex.EncodeToString(hashBytes)

	// Invent other things
	ctime := time.Now().Unix()

	// Data structure

	return DataSource.Torrent{
		Name:                    name,
		IsFinished:              true,
		Id:                      id,
		Eta:                     -1,
		HashString:              hashString,
		MetadataPercentComplete: 1,
		AddedDate:               ctime,
		ActivityDate:            ctime,

		Trackers:     make([]DataSource.Tracker, 0),
		Files:        make([]DataSource.File, 0),
		FileStats:    make([]DataSource.FileStats, 0),
		Peers:        make([]DataSource.Peer, 0),
		Pieces:       make([]byte, 0),
		Priorities:   make([]int64, 0),
		TrackerStats: make([]DataSource.TrackerStats, 0),
		Wanted:       make([]bool, 0),
		Webseeds:     make([]DataSource.Webseed, 0),
	}

}

func (this *sampleDataSession) reset() {
	this.torrents = []DataSource.Torrent{
		fakeTorrent(1, "hello world!"),
	}
	this.updateCounter = 1
}

func (this *sampleDataSession) Start(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) StartNow(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) Stop(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) Verify(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) Reannounce(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) Update(torrents DataSource.TorrentSelection, properties map[string]interface{}) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) MonotonicUpdateCounter() int64 {
	return this.updateCounter
}

func (this *sampleDataSession) Get() ([]DataSource.Torrent, error) {
	return this.torrents, nil
}

func (this *sampleDataSession) Add(properties map[string]interface{}) (DataSource.TorrentAddResponse, error) {

	filename, ok := properties["filename"].(string)
	if !ok {
		return DataSource.TorrentAddResponse{}, errors.New("Filename not specified")
	}

	// add to our little list
	t := fakeTorrent(int64(len(this.torrents)+1), fmt.Sprintf("You just typed '%s'!", filename))
	this.torrents = append(this.torrents, t)
	this.updateCounter += 1

	ret := DataSource.TorrentAddResponse{
		DidAlreadyExist: false,

		HashString: t.HashString,
		ID:         t.Id,
		Name:       t.Name,
	}

	return ret, nil
}

func (this *sampleDataSession) Remove(torrents DataSource.TorrentSelection) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) SetLocation(torrents DataSource.TorrentSelection, Location string, Move bool) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) RenamePath(torrents DataSource.TorrentSelection, Path, Name string) error {
	return ErrNotImplemented
}

func (this *sampleDataSession) UpdateSession(properties map[string]interface{}) error {
	return nil // fake acceptance
}

func (this *sampleDataSession) Session() (DataSource.Session, error) {
	return DataSource.Session{
		RpcVersion:        15,
		RpcVersionMinimum: 1,
		Version:           "2.92 (trpcd-sampledata)",
	}, nil
}

func (this *sampleDataSession) SessionStats() (DataSource.SessionStats, error) {
	return DataSource.SessionStats{
		ActiveTorrentCount: int64(len(this.torrents)),
		PausedTorrentCount: 0,
		TorrentCount:       int64(len(this.torrents)),
	}, nil
}

func (this *sampleDataSession) UpdateBlocklist() error {
	return nil // fake acceptance
}

func (this *sampleDataSession) MoveUp(torrents DataSource.TorrentSelection) error {
	return nil // fake acceptance
}

func (this *sampleDataSession) MoveDown(torrents DataSource.TorrentSelection) error {
	return nil // fake acceptance
}

func (this *sampleDataSession) MoveToTop(torrents DataSource.TorrentSelection) error {
	return nil // fake acceptance
}

func (this *sampleDataSession) MoveToBottom(torrents DataSource.TorrentSelection) error {
	return nil // fake acceptance
}

func (this *sampleDataSession) FreeSpace(Path string) (int64, error) {
	return (1 * 1024 * 1024 * 1024 * 1024), nil // fake 1TB
}
