// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package binarylib

import (
	"bytes"
	"crypto/sha256"
	"io/ioutil"
	"os"
	"path/filepath"
	"reflect"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/services/repository"
	"v.io/x/lib/vlog"

	"v.io/x/ref/test"
	"v.io/x/ref/test/testutil"
)

//go:generate v23 test generate

const (
	v23Prefix = "vanadium_binary_repository"
)

func setupRepository(t *testing.T, ctx *context.T) (string, func()) {
	// Setup the root of the binary repository.
	rootDir, err := ioutil.TempDir("", v23Prefix)
	if err != nil {
		t.Fatalf("TempDir() failed: %v", err)
	}
	path, perm := filepath.Join(rootDir, VersionFile), os.FileMode(0600)
	if err := ioutil.WriteFile(path, []byte(Version), perm); err != nil {
		vlog.Fatalf("WriteFile(%v, %v, %v) failed: %v", path, Version, perm, err)
	}
	// Setup and start the binary repository server.
	server, err := v23.NewServer(ctx)
	if err != nil {
		t.Fatalf("NewServer() failed: %v", err)
	}
	depth := 2
	state, err := NewState(rootDir, "http://test-root-url", depth)
	if err != nil {
		t.Fatalf("NewState(%v, %v) failed: %v", rootDir, depth, err)
	}

	dispatcher, err := NewDispatcher(v23.GetPrincipal(ctx), state)
	if err != nil {
		t.Fatalf("NewDispatcher() failed: %v\n", err)
	}
	l := v23.GetListenSpec(ctx)
	endpoints, err := server.Listen(l)
	if err != nil {
		t.Fatalf("Listen(%s) failed: %v", l, err)
	}
	suffix := ""
	if err := server.ServeDispatcher(suffix, dispatcher); err != nil {
		t.Fatalf("Serve(%v, %v) failed: %v", suffix, dispatcher, err)
	}
	von := naming.JoinAddressName(endpoints[0].String(), "test")
	return von, func() {
		if err := os.Remove(path); err != nil {
			t.Fatalf("Remove(%v) failed: %v", path, err)
		}
		// Check that any directories and files that were created to
		// represent the binary objects have been garbage collected.
		if err := os.RemoveAll(rootDir); err != nil {
			t.Fatalf("Remove(%v) failed: %v", rootDir, err)
		}
		// Shutdown the binary repository server.
		if err := server.Stop(); err != nil {
			t.Fatalf("Stop() failed: %v", err)
		}
	}
}

// TestBufferAPI tests the binary repository client-side library
// interface using buffers.
func TestBufferAPI(t *testing.T) {
	ctx, shutdown := test.InitForTest()
	defer shutdown()

	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	von, cleanup := setupRepository(t, ctx)
	defer cleanup()
	data := testutil.RandomBytes(testutil.Intn(10 << 20))
	mediaInfo := repository.MediaInfo{Type: "application/octet-stream"}
	sig, err := Upload(ctx, von, data, mediaInfo)
	if err != nil {
		t.Fatalf("Upload(%v) failed: %v", von, err)
	}
	p := v23.GetPrincipal(ctx)
	if sig != nil {
		// verify the principal signature
		h := sha256.Sum256(data)
		if !sig.Verify(p.PublicKey(), h[:]) {
			t.Fatalf("Failed to verify upload signature(%v)", sig)
		}
	} else {
		t.Fatalf("Upload(%v) failed to generate principal(%v) signature", von, p)
	}
	output, outInfo, err := Download(ctx, von)
	if err != nil {
		t.Fatalf("Download(%v) failed: %v", von, err)
	}
	if bytes.Compare(data, output) != 0 {
		t.Errorf("Data mismatch:\nexpected %v %v\ngot %v %v", len(data), data[:100], len(output), output[:100])
	}
	if err := Delete(ctx, von); err != nil {
		t.Errorf("Delete(%v) failed: %v", von, err)
	}
	if _, _, err := Download(ctx, von); err == nil {
		t.Errorf("Download(%v) did not fail", von)
	}
	if !reflect.DeepEqual(mediaInfo, outInfo) {
		t.Errorf("unexpected media info: expected %v, got %v", mediaInfo, outInfo)
	}
}

// TestFileAPI tests the binary repository client-side library
// interface using files.
func TestFileAPI(t *testing.T) {
	ctx, shutdown := test.InitForTest()
	defer shutdown()

	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	von, cleanup := setupRepository(t, ctx)
	defer cleanup()
	// Create up to 10MB of random bytes.
	data := testutil.RandomBytes(testutil.Intn(10 << 20))
	dir, prefix := "", ""
	src, err := ioutil.TempFile(dir, prefix)
	if err != nil {
		t.Fatalf("TempFile(%v, %v) failed: %v", dir, prefix, err)
	}
	defer os.Remove(src.Name())
	defer src.Close()
	dstdir, err := ioutil.TempDir(dir, prefix)
	if err != nil {
		t.Fatalf("TempDir(%v, %v) failed: %v", dir, prefix, err)
	}
	defer os.RemoveAll(dstdir)
	dst, err := ioutil.TempFile(dstdir, prefix)
	if err != nil {
		t.Fatalf("TempFile(%v, %v) failed: %v", dstdir, prefix, err)
	}
	defer dst.Close()
	if _, err := src.Write(data); err != nil {
		t.Fatalf("Write() failed: %v", err)
	}
	if _, err := UploadFromFile(ctx, von, src.Name()); err != nil {
		t.Fatalf("UploadFromFile(%v, %v) failed: %v", von, src.Name(), err)
	}
	if err := DownloadToFile(ctx, von, dst.Name()); err != nil {
		t.Fatalf("DownloadToFile(%v, %v) failed: %v", von, dst.Name(), err)
	}
	output, err := ioutil.ReadFile(dst.Name())
	if err != nil {
		t.Errorf("ReadFile(%v) failed: %v", dst.Name(), err)
	}
	if bytes.Compare(data, output) != 0 {
		t.Errorf("Data mismatch:\nexpected %v %v\ngot %v %v", len(data), data[:100], len(output), output[:100])
	}
	jMediaInfo, err := ioutil.ReadFile(dst.Name() + ".__info")
	if err != nil {
		t.Errorf("ReadFile(%v) failed: %v", dst.Name()+".__info", err)
	}
	if expected := `{"Type":"application/octet-stream","Encoding":""}`; string(jMediaInfo) != expected {
		t.Errorf("unexpected media info: expected %q, got %q", expected, string(jMediaInfo))
	}
	if err := Delete(ctx, von); err != nil {
		t.Errorf("Delete(%v) failed: %v", von, err)
	}
}

// TestDownloadUrl tests the binary repository client-side library
// DownloadUrl method.
func TestDownloadUrl(t *testing.T) {
	ctx, shutdown := test.InitForTest()
	defer shutdown()

	v23.GetNamespace(ctx).CacheCtl(naming.DisableCache(true))

	von, cleanup := setupRepository(t, ctx)
	defer cleanup()
	url, _, err := DownloadUrl(ctx, von)
	if err != nil {
		t.Fatalf("DownloadUrl(%v) failed: %v", von, err)
	}
	if got, want := url, "http://test-root-url/test"; got != want {
		t.Fatalf("unexpect output: got %v, want %v", got, want)
	}
}
