// Copyright 2017 The Fuchsia 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 daemon

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"syscall"
	"syscall/zx"
	"syscall/zx/fidl"
	zxio "syscall/zx/io"
	"testing"
	"thinfs/fs"
	"thinfs/zircon/rpc"

	"fidl/fuchsia/amber"

	"fuchsia.googlesource.com/merkle"
	"fuchsia.googlesource.com/pmd/amberer"
	"fuchsia.googlesource.com/pmd/pkgfs"
	tuf "github.com/flynn/go-tuf"
)

func TestSources(t *testing.T) {
	store, err := ioutil.TempDir("", "amber-test")
	if err != nil {
		panic(err)
	}
	defer os.RemoveAll(store)

	d, err := NewDaemon(store, "", "", nil)
	if err != nil {
		panic(err)
	}

	t.Run("Add", func(t *testing.T) {
		if err := d.AddSource(&amber.SourceConfig{
			Id:      "addtest",
			RepoUrl: "http://localhost/addtest",
			RootKeys: []amber.KeyConfig{
				amber.KeyConfig{
					Type:  "ed25519",
					Value: "be0b983f7396da675c40c6b93e47fced7c1e9ea8a32a1fe952ba8f519760b307",
				},
			},
			StatusConfig: &amber.StatusConfig{Enabled: true},
		}); err != nil {
			t.Fatal(err)
		}

		if d.GetSources()["addtest"] == nil {
			t.Errorf("source missing after add, got %#v", d.GetSources())
		}
	})

	t.Run("Remove", func(t *testing.T) {
		if err := d.AddSource(&amber.SourceConfig{
			Id:      "removetest",
			RepoUrl: "http://localhost/removetest",
			RootKeys: []amber.KeyConfig{
				amber.KeyConfig{
					Type:  "ed25519",
					Value: "be0b983f7396da675c40c6b93e47fced7c1e9ea8a32a1fe952ba8f519760b307",
				},
			},
			StatusConfig: &amber.StatusConfig{Enabled: true},
		}); err != nil {
			t.Fatal(err)
		}

		if _, err := d.RemoveSource("removetest"); err != nil {
			t.Fatal(err)
		}
		if s := d.GetSources()["removetest"]; s != nil {
			t.Errorf("expected source to be removed, got %#v", s)
		}
	})

	t.Run("Disable", func(t *testing.T) {
		if err := d.AddSource(&amber.SourceConfig{
			Id:      "disabletest",
			RepoUrl: "http://localhost/disabletest",
			RootKeys: []amber.KeyConfig{
				amber.KeyConfig{
					Type:  "ed25519",
					Value: "be0b983f7396da675c40c6b93e47fced7c1e9ea8a32a1fe952ba8f519760b307",
				},
			},
			StatusConfig: &amber.StatusConfig{Enabled: true},
		}); err != nil {
			t.Fatal(err)
		}

		if d.GetActiveSources()["disabletest"] == nil {
			t.Fatal("expected source to be enabled initially")
		}

		d.DisableSource("disabletest")

		if d.GetActiveSources()["disabletest"] != nil {
			t.Fatal("expected source to be disabled")
		}
	})

	t.Run("Enable", func(t *testing.T) {
		if err := d.AddSource(&amber.SourceConfig{
			Id:      "enabletest",
			RepoUrl: "http://localhost/enabletest",
			RootKeys: []amber.KeyConfig{
				amber.KeyConfig{
					Type:  "ed25519",
					Value: "be0b983f7396da675c40c6b93e47fced7c1e9ea8a32a1fe952ba8f519760b307",
				},
			},
			StatusConfig: &amber.StatusConfig{Enabled: true},
		}); err != nil {
			t.Fatal(err)
		}

		d.DisableSource("enabletest")
		if d.GetActiveSources()["enabletest"] != nil {
			t.Fatal("expected source to be disabled")
		}

		d.EnableSource("enabletest")
		if d.GetActiveSources()["enabletest"] == nil {
			t.Fatal("expected source to be enabled")
		}
	})

	t.Run("Login", func(t *testing.T) {
		t.Skip("TODO: add coverage for oauth2")
	})
}

func panicerr(err error) {
	if err != nil {
		panic(err)
	}
}

func makeBlob(dir, content string) (string, error) {
	var t merkle.Tree
	if _, err := t.ReadFrom(strings.NewReader(content)); err != nil {
		return "", err
	}
	merkleroot := fmt.Sprintf("%x", t.Root())
	path := filepath.Join(dir, merkleroot)
	return merkleroot, ioutil.WriteFile(path, []byte(content), 0644)
}

func initRepo(repoDir string, store string, blobs []string) *tuf.Repo {
	// create and copy the package into the repo staging dir
	sTargetsDir := repoDir + "/staged/targets"
	panicerr(os.MkdirAll(sTargetsDir+"/foo", 0755))
	stagedPkg := sTargetsDir + "/foo/0"
	pkgBlob := blobs[0]
	panicerr(os.Link(store+"/"+pkgBlob, stagedPkg))

	panicerr(os.MkdirAll(repoDir+"/repository/blobs", 0755))
	for _, blob := range blobs {
		panicerr(os.Link(store+"/"+blob, repoDir+"/repository/blobs/"+blob))
	}

	// create the repo
	repo, err := tuf.NewRepo(tuf.FileSystemStore(repoDir, nil), "sha512")
	panicerr(err)
	panicerr(repo.Init(true))
	_, err = repo.GenKey("root")
	panicerr(err)
	_, err = repo.GenKey("targets")
	panicerr(err)
	_, err = repo.GenKey("snapshot")
	panicerr(err)
	_, err = repo.GenKey("timestamp")
	panicerr(err)
	panicerr(repo.AddTarget("/foo/0", json.RawMessage(fmt.Sprintf(`{"merkle": %q}`, pkgBlob))))
	panicerr(repo.Snapshot(tuf.CompressionTypeNone))
	panicerr(repo.Timestamp())
	panicerr(repo.Commit())
	return repo
}

func TestDaemon(t *testing.T) {
	store, err := ioutil.TempDir("", "amber-test-store")
	panicerr(err)
	defer os.RemoveAll(store)

	// TODO(raggi): make this a real package instead, but that's a lot more setup
	pkgContent := "very fake package"
	pkgBlobLength := int64(len(pkgContent))
	pkgBlob, err := makeBlob(store, pkgContent)
	panicerr(err)
	root1, err := makeBlob(store, "first blob")
	panicerr(err)

	repoDir, err := ioutil.TempDir("", "amber-test-repo")
	panicerr(err)
	defer os.RemoveAll(repoDir)

	// initialize the repo, adding the staged target
	repo := initRepo(repoDir, store, []string{pkgBlob, root1})
	keys, err := repo.RootKeys()
	panicerr(err)
	rootKey := keys[0]

	server := httptest.NewServer(http.FileServer(http.Dir(repoDir + "/repository")))

	// XXX(raggi): cleanup disabled because networking bug!
	// defer server.Close()
	// // so that the httptest server can close:
	// defer http.DefaultTransport.(*http.Transport).CloseIdleConnections()

	store, err = ioutil.TempDir("", "amber-test")
	panicerr(err)
	defer os.RemoveAll(store)

	pkgsDir, err := ioutil.TempDir("", "amber-test-pkgs")
	panicerr(err)
	defer os.RemoveAll(pkgsDir)
	blobsDir, err := ioutil.TempDir("", "amber-test-blobs")
	panicerr(err)
	defer os.RemoveAll(blobsDir)

	d, err := NewDaemon(store, pkgsDir, blobsDir, nil)
	panicerr(err)

	err = d.AddSource(&amber.SourceConfig{
		Id:          "testing",
		RepoUrl:     server.URL,
		BlobRepoUrl: server.URL + "/blobs",
		// TODO(raggi): fix keyconfig
		RootKeys: []amber.KeyConfig{
			amber.KeyConfig{
				Type:  rootKey.Type,
				Value: rootKey.Value.Public.String(),
			},
		},
		StatusConfig: &amber.StatusConfig{Enabled: true},
	})
	panicerr(err)

	// TODO(raggi): add test for the update semantics
	d.Update()

	merkle, length, err := d.MerkleFor("foo", "0", "")
	if err != nil {
		t.Fatal(err)
	}
	if merkle != pkgBlob {
		t.Errorf("merkleFor: got %q, want %q", merkle, pkgBlob)
	}
	if length != int64(pkgBlobLength) {
		t.Errorf("merkleFor length: got %d, want %d", length, pkgBlobLength)
	}

	// TODO(raggi): add coverage for error propagatation cases
	var rootSeen string
	var errSeen error
	d.AddWatch(pkgBlob, func(root string, err error) {
		rootSeen = root
		errSeen = err
	})
	panicerr(d.GetPkg(pkgBlob, pkgBlobLength))

	d.Activated(pkgBlob)

	if rootSeen != pkgBlob {
		t.Errorf("activation: got %q, want %q", rootSeen, pkgBlob)
	}
	panicerr(errSeen)

	c, err := ioutil.ReadFile(pkgsDir + "/" + pkgBlob)
	panicerr(err)
	if got := string(c); got != pkgContent {
		t.Errorf("getpkg: got %q, want %q", got, pkgContent)
	}

	panicerr(d.GetBlob(root1))

	c, err = ioutil.ReadFile(blobsDir + "/" + root1)
	panicerr(err)
	if got, want := string(c), "first blob"; got != want {
		t.Errorf("getblob: got %q, want %q", got, want)
	}
}

// Mock blobfs that always returns "no space".

type blobfsFile struct {
	pkgfs.UnsupportedFile
}

func (f blobfsFile) Truncate(size uint64) error {
	return fs.ErrNoSpace
}

var _ = fs.File(blobfsFile{})

type blobfsDirectory struct {
	pkgfs.UnsupportedDirectory
}

func (d blobfsDirectory) Open(name string, flags fs.OpenFlags) (fs.File, fs.Directory, *fs.Remote, error) {
	return blobfsFile{}, nil, nil, nil
}

var _ = fs.Directory(blobfsDirectory{})

type blobfsFilesystem struct {
	serveChannel zx.Channel
}

func (fs *blobfsFilesystem) Mount(path string) error {
	var err error
	err = os.MkdirAll(path, os.ModePerm)
	panicerr(err)
	parentFd, err := syscall.Open(path, syscall.O_ADMIN|syscall.O_DIRECTORY, 0777)
	panicerr(err)
	var rpcChan, mountChan zx.Channel
	rpcChan, mountChan, err = zx.NewChannel(0)
	panicerr(err)
	remote := zxio.DirectoryInterface(fidl.InterfaceRequest{Channel: mountChan})
	dirChan := zx.Channel(syscall.FDIOForFD(parentFd).Handles()[0])
	dir := zxio.DirectoryAdminInterface(fidl.InterfaceRequest{Channel: dirChan})
	panicerr(err)
	status, err := dir.Mount(remote)
	if zx.Status(status) != zx.ErrOk {
		panic(fmt.Sprintf("Mount error: %s", zx.Status(status)))
	}
	panicerr(err)
	fs.Serve(rpcChan)
	return nil
}

func (fs *blobfsFilesystem) Unmount() {
	// Just a test, let this be a no-op.
}

// Starts a Directory protocol RPC server on the given channel. Does not block.
func (fs *blobfsFilesystem) Serve(c zx.Channel) error {
	// rpc.NewServer takes ownership of the Handle and will close it on error.
	vfs, err := rpc.NewServer(fs, zx.Handle(c))
	if err != nil {
		return fmt.Errorf("vfs server creation: %s", err)
	}
	fs.serveChannel = c

	// TODO(raggi): serve has no quit/shutdown path.
	for i := runtime.NumCPU(); i > 0; i-- {
		go vfs.Serve()
	}
	return nil
}

func (fs *blobfsFilesystem) Blockcount() int64 {
	return 0
}

func (fs *blobfsFilesystem) Blocksize() int64 {
	return 0
}

func (fs *blobfsFilesystem) Size() int64 {
	return 0
}

func (fs *blobfsFilesystem) Close() error {
	fs.Unmount()
	return nil
}

func (fs *blobfsFilesystem) RootDirectory() fs.Directory {
	return blobfsDirectory{}
}

func (fs *blobfsFilesystem) Type() string {
	return "blobfs"
}

func (fs *blobfsFilesystem) FreeSize() int64 {
	return 0
}

func (fs *blobfsFilesystem) DevicePath() string {
	return ""
}

var _ = fs.FileSystem(&blobfsFilesystem{})

type eventsImpl struct{}

var _ = amber.Events(eventsImpl{})

func TestOutOfSpace(t *testing.T) {
	var err error

	// Fake blobfs that always returns fs.ErrNoSpace.
	blobfsRootPath, err := ioutil.TempDir("", "pkgfs-test-blobfs")
	defer os.RemoveAll(blobfsRootPath)
	panicerr(err)

	blobfsPath := filepath.Join(blobfsRootPath, "blobfs")
	var fs blobfsFilesystem
	fs.Mount(blobfsPath)
	defer fs.Unmount()

	// Set up pkgfs.

	indexPath, err := ioutil.TempDir("", "pkgfs-test-index")
	if err != nil {
		panic(err)
	}
	panicerr(err)
	defer os.RemoveAll(indexPath)

	pkgfs, err := pkgfs.New(indexPath, blobfsPath, amberer.NewAmberClient())
	panicerr(err)

	pkgfsDir, err := ioutil.TempDir("", "pkgfs-test-mount")
	panicerr(err)
	defer os.RemoveAll(pkgfsDir)

	go func() {
		if err := pkgfs.Mount(pkgfsDir); err != nil {
			panic(err)
		}
	}()
	defer pkgfs.Unmount()

	// Set up daemon.

	store, err := ioutil.TempDir("", "amber-test")
	panicerr(err)
	defer os.RemoveAll(store)

	installPkgDir := filepath.Join(pkgfsDir, "install/pkg")
	installBlobDir := filepath.Join(pkgfsDir, "install/blob")
	var evtSvc amber.EventsService
	d, err := NewDaemon(store, installPkgDir, installBlobDir, &evtSvc)
	panicerr(err)

	// Create a fake package and blob.

	// TODO(raggi): make this a real package instead, but that's a lot more setup
	pkgContent := "very fake package"
	pkgBlob, err := makeBlob(store, pkgContent)
	panicerr(err)
	root1Content := "first blob"
	root1Length := int64(len(root1Content))
	root1, err := makeBlob(store, root1Content)
	panicerr(err)

	// Add a source.

	repoDir, err := ioutil.TempDir("", "amber-test-repo")
	panicerr(err)
	defer os.RemoveAll(repoDir)
	repo := initRepo(repoDir, store, []string{pkgBlob, root1})
	keys, err := repo.RootKeys()
	panicerr(err)

	rootKey := keys[0]
	server := httptest.NewServer(http.FileServer(http.Dir(repoDir + "/repository")))

	// XXX(raggi): cleanup disabled because networking bug!
	// defer server.Close()
	// // so that the httptest server can close:
	// defer http.DefaultTransport.(*http.Transport).CloseIdleConnections()

	err = d.AddSource(&amber.SourceConfig{
		Id:          "testing",
		RepoUrl:     server.URL,
		BlobRepoUrl: server.URL + "/blobs",
		// TODO(raggi): fix keyconfig
		RootKeys: []amber.KeyConfig{
			amber.KeyConfig{
				Type:  rootKey.Type,
				Value: rootKey.Value.Public.String(),
			},
		},
		StatusConfig: &amber.StatusConfig{Enabled: true},
	})
	panicerr(err)

	// Fetch into daemon and check that the event was signaled.
	req, evtIfc, err := amber.NewEventsInterfaceRequest()
	panicerr(err)
	_, err = evtSvc.Add(eventsImpl{}, req.ToChannel(), nil)
	panicerr(err)
	err = d.fetchInto(root1, root1Length, installBlobDir)
	if e, ok := err.(zx.Error); ok && e.Status == zx.ErrNoSpace {
		// Expected.
	} else {
		panic(fmt.Sprintf("fetchInto returned unexpected error %s", err))
	}
	err = evtIfc.ExpectOnOutOfSpace()
	panicerr(err)
}
