package liber

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"strconv"
	"testing"
)

func newTestSyncHttpServer(db *Database, updir string) *httptest.Server {
	localsrv := &syncServer{db, &FileStorage{Root: updir, Nesting: 2}}

	mux := http.NewServeMux()
	mux.HandleFunc("/api/sync/upload", localsrv.handleSyncUpload)
	mux.HandleFunc("/api/sync/diff", localsrv.handleDiffRequest)

	return httptest.NewServer(mux)
}

func TestSync_Sync(t *testing.T) {
	// Create a temporary directory to store uploads.
	updir, _ := ioutil.TempDir("", "ebook-upload-")
	defer os.RemoveAll(updir)

	td, db := newTestDatabase(t)
	defer td.Close()

	td2, db2 := newTestDatabase(t)
	defer td2.Close()

	for i := 0; i < 10; i++ {
		bookid := NewID()
		db.PutBook(&Book{
			Id: bookid,
			Metadata: &Metadata{
				Title:   fmt.Sprintf("Book #%d", i+1),
				Creator: []string{"Random Author"},
				ISBN:    []string{strconv.Itoa(i + 1)},
			},
		})
		db.PutFile(testEpubFile(updir, bookid))
	}

	// Run a sync from db to db2.
	srv := newTestSyncHttpServer(db2, updir)
	defer srv.Close()

	cl := NewRemoteServer(srv.URL)
	err := db.Sync(cl)
	if err != nil {
		t.Fatalf("Sync(): %v", err)
	}

	// Ensure that books are present in db2.
	for i := 0; i < 10; i++ {
		metatmpl := &Metadata{
			ISBN: []string{strconv.Itoa(i + 1)},
		}
		if _, err := db2.Find(metatmpl); err != nil {
			t.Errorf("Book %d missing from db2: %v", i+1, err)
		}
	}
}