package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"path/filepath"

	"github.com/flynn/go-tuf/data"
	"github.com/flynn/go-tuf/util"
	. "gopkg.in/check.v1"

	goTufGenerator "github.com/flynn/go-tuf/client/testdata/go-tuf/generator"
)

type InteropSuite struct{}

var _ = Suite(&InteropSuite{})

func (InteropSuite) TestGoClientIdentityConsistentSnapshotFalse(c *C) {
	checkGoIdentity(c, false)
}

func (InteropSuite) TestGoClientIdentityConsistentSnapshotTrue(c *C) {
	checkGoIdentity(c, true)
}

func checkGoIdentity(c *C, consistentSnapshot bool) {
	cwd, err := os.Getwd()
	c.Assert(err, IsNil)
	testDataDir := filepath.Join(cwd, "testdata")

	tempDir, err := ioutil.TempDir("", "")
	c.Assert(err, IsNil)
	defer os.RemoveAll(tempDir)

	// Generate the metadata and compute hashes for all the files.
	goTufGenerator.Generate(tempDir, filepath.Join(testDataDir, "keys.json"), consistentSnapshot)
	hashes := computeHashes(c, tempDir)

	snapshotDir := filepath.Join(testDataDir, "go-tuf", fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot))
	snapshotHashes := computeHashes(c, snapshotDir)

	c.Assert(hashes, DeepEquals, snapshotHashes, Commentf("metadata out of date, regenerate by running client/testdata/go-tuf/regenerate-metadata.sh"))
}

func computeHashes(c *C, dir string) map[string]string {
	hashes := make(map[string]string)

	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}

		bytes, err := ioutil.ReadFile(path)
		if err != nil {
			return err
		}

		path, err = filepath.Rel(dir, path)
		if err != nil {
			return err
		}
		hashes[path] = string(bytes)

		return nil
	})
	c.Assert(err, IsNil)

	return hashes
}

func (InteropSuite) TestGoClientCompatibility(c *C) {
	names := []string{
		"go-tuf",
		"go-tuf-transition-M3",
		"go-tuf-transition-M4",
	}
	options := &HTTPRemoteOptions{MetadataPath: "", TargetsPath: "targets"}

	for _, name := range names {
		for _, consistentSnapshot := range []bool{false, true} {
			t := newTestCase(c, name, consistentSnapshot, options)
			t.run(c)
		}
	}
}

type testCase struct {
	name               string
	consistentSnapshot bool
	options            *HTTPRemoteOptions
	local              LocalStore
	targets            map[string][]byte
	testDir            string
	testSteps          []string
}

func newTestCase(c *C, name string, consistentSnapshot bool, options *HTTPRemoteOptions) testCase {
	cwd, err := os.Getwd()
	c.Assert(err, IsNil)
	testDir := filepath.Join(cwd, "testdata", name, fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot))

	dirEntries, err := ioutil.ReadDir(testDir)
	c.Assert(err, IsNil)
	c.Assert(dirEntries, Not(HasLen), 0)

	testSteps := []string{}
	for _, dirEntry := range dirEntries {
		if dirEntry.IsDir() {
			testSteps = append(testSteps, dirEntry.Name())
		}
	}

	return testCase{
		name:               name,
		consistentSnapshot: consistentSnapshot,
		options:            options,
		local:              MemoryLocalStore(),
		targets:            make(map[string][]byte),
		testDir:            testDir,
		testSteps:          testSteps,
	}
}

func (t *testCase) run(c *C) {
	c.Logf("test case: %s consistent-snapshot: %t", t.name, t.consistentSnapshot)

	init := true
	for _, stepName := range t.testSteps {
		t.runStep(c, stepName, init)
		init = false
	}
}

func (t *testCase) runStep(c *C, stepName string, init bool) {
	c.Logf("step: %s", stepName)

	addr, cleanup := startFileServer(c, t.testDir)
	defer cleanup()

	remote, err := HTTPRemoteStore(fmt.Sprintf("http://%s/%s/repository", addr, stepName), t.options, nil)
	c.Assert(err, IsNil)

	client := NewClient(t.local, remote)

	// initiate a client with the root keys
	if init {
		keys := getKeys(c, remote)
		c.Assert(client.Init(keys, 1), IsNil)
	}

	// check update returns the correct updated targets
	files, err := client.Update()
	c.Assert(err, IsNil)
	c.Assert(files, HasLen, 1)

	targetName := stepName
	t.targets[targetName] = []byte(targetName)

	file, ok := files[targetName]
	if !ok {
		c.Fatalf("expected updated targets to contain %s", targetName)
	}

	data := t.targets[targetName]
	meta, err := util.GenerateTargetFileMeta(bytes.NewReader(data), file.HashAlgorithms()...)
	c.Assert(err, IsNil)
	c.Assert(util.TargetFileMetaEqual(file, meta), IsNil)

	// download the files and check they have the correct content
	for name, data := range t.targets {
		for _, prefix := range []string{"", "/"} {
			var dest testDestination
			c.Assert(client.Download(prefix+name, &dest), IsNil)
			c.Assert(dest.deleted, Equals, false)
			c.Assert(dest.String(), Equals, string(data))
		}
	}
}

func startFileServer(c *C, dir string) (string, func() error) {
	l, err := net.Listen("tcp", "127.0.0.1:0")
	c.Assert(err, IsNil)
	addr := l.Addr().String()
	go http.Serve(l, http.FileServer(http.Dir(dir)))
	return addr, l.Close
}

func getKeys(c *C, remote RemoteStore) []*data.Key {
	r, _, err := remote.GetMeta("root.json")
	c.Assert(err, IsNil)

	type SignedRoot struct {
		Signed data.Root
	}
	root := &SignedRoot{}
	err = json.NewDecoder(r).Decode(&root)
	c.Assert(err, IsNil)

	rootRole, exists := root.Signed.Roles["root"]
	c.Assert(exists, Equals, true)

	rootKeys := []*data.Key{}

	for _, keyID := range rootRole.KeyIDs {
		key, exists := root.Signed.Keys[keyID]
		c.Assert(exists, Equals, true)

		rootKeys = append(rootKeys, key)
	}

	c.Assert(rootKeys, Not(HasLen), 0)

	return rootKeys
}
