// 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 main

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

	"fuchsia.googlesource.com/jiri/jiritest"
	"fuchsia.googlesource.com/jiri/project"
)

// Setup two snapshots and also return their diff
func setUpSnapshots(t *testing.T, rootDir string) ([]byte, []byte, *Diff) {
	n := 7
	m1 := &project.Manifest{Version: project.ManifestVersion}
	m2 := &project.Manifest{Version: project.ManifestVersion}
	m1.Projects = make([]project.Project, n)
	m2.Projects = make([]project.Project, n)
	for i := 0; i < n; i++ {
		m1.Projects[i].Name = fmt.Sprintf("project-%d", i)
		m1.Projects[i].Remote = "remote-url"
		m1.Projects[i].Revision = fmt.Sprintf("revision-%d", i)
		m1.Projects[i].GerritHost = ""
		m1.Projects[i].Path = fmt.Sprintf("path-%d", i)
		m2.Projects[i] = m1.Projects[i]
	}

	d := &Diff{}
	d.NewProjects = make([]DiffProject, 2)
	d.DeletedProjects = make([]DiffProject, 2)
	d.UpdatedProjects = make([]DiffProject, 2)

	//Simulate delete and new
	i := 2
	d.DeletedProjects[0].Name = m1.Projects[i].Name
	d.DeletedProjects[0].Remote = m1.Projects[i].Remote
	d.DeletedProjects[0].Path = filepath.Join(rootDir, m1.Projects[i].Path)
	d.DeletedProjects[0].Revision = m1.Projects[i].Revision
	d.NewProjects[0] = d.DeletedProjects[0]
	m2.Projects[i].Name = fmt.Sprintf("new-project-%d", i)
	m2.Projects[i].Path = fmt.Sprintf("new-path-%d", i)
	d.NewProjects[0].Name = m2.Projects[i].Name
	d.NewProjects[0].Path = filepath.Join(rootDir, m2.Projects[i].Path)

	i = 4
	d.DeletedProjects[1].Name = m1.Projects[i].Name
	d.DeletedProjects[1].Remote = m1.Projects[i].Remote
	d.DeletedProjects[1].Path = filepath.Join(rootDir, m1.Projects[i].Path)
	d.DeletedProjects[1].Revision = m1.Projects[i].Revision
	d.NewProjects[1] = d.DeletedProjects[1]
	m2.Projects[i].Name = fmt.Sprintf("new-project-%d", i)
	m2.Projects[i].Path = fmt.Sprintf("new-path-%d", i)
	d.NewProjects[1].Name = m2.Projects[i].Name
	d.NewProjects[1].Path = filepath.Join(rootDir, m2.Projects[i].Path)

	// update revision
	i = 0
	m2.Projects[i].Revision = fmt.Sprintf("new-rev-%d", i)
	d.UpdatedProjects[0].Name = m1.Projects[i].Name
	d.UpdatedProjects[0].Remote = m1.Projects[i].Remote
	d.UpdatedProjects[0].Path = filepath.Join(rootDir, m1.Projects[i].Path)
	d.UpdatedProjects[0].OldRevision = m1.Projects[i].Revision
	d.UpdatedProjects[0].Revision = m2.Projects[i].Revision
	d.UpdatedProjects[0].Error = "no gerrit host"

	// move project
	i = 1
	m2.Projects[i].Path = fmt.Sprintf("new-path-%d", i)
	d.UpdatedProjects[1].Name = m1.Projects[i].Name
	d.UpdatedProjects[1].Remote = m1.Projects[i].Remote
	d.UpdatedProjects[1].Path = filepath.Join(rootDir, m2.Projects[i].Path)
	d.UpdatedProjects[1].OldPath = filepath.Join(rootDir, m1.Projects[i].Path)
	d.UpdatedProjects[1].Revision = m1.Projects[i].Revision

	// rename project
	i = 3
	m2.Projects[i].Name = fmt.Sprintf("new-project-%d", i)
	b1, err := m1.ToBytes()
	if err != nil {
		t.Fatal(err)
	}

	b2, err := m2.ToBytes()
	if err != nil {
		t.Fatal(err)
	}
	return b1, b2, d.Sort()

}

func TestDiffLocalSnapshots(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()
	s1, s2, d := setUpSnapshots(t, fake.X.Root)
	if string(s1) == string(s2) {
		t.Fatal("e")
	}
	want, err := json.Marshal(d)
	if err != nil {
		t.Fatal(err)
	}
	t1, err := ioutil.TempFile("", "test-diff")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(t1.Name())
	defer t1.Close()
	if _, err := t1.Write(s1); err != nil {
		t.Fatal(err)
	}
	t1.Sync()

	t2, err := ioutil.TempFile("", "test-diff")
	if err != nil {
		t.Fatal(err)
	}
	defer os.Remove(t2.Name())
	defer t2.Close()
	if _, err := t2.Write(s2); err != nil {
		t.Fatal(err)
	}
	t2.Sync()

	diff, err := getDiff(fake.X, t1.Name(), t2.Name())
	if err != nil {
		t.Fatal(err)
	}
	got, err := json.Marshal(diff)
	if err != nil {
		t.Fatal(err)
	}
	if string(got) != string(want) {
		t.Fatalf("Error, got: %s\n\nwant:%s", got, want)
	}
}

func TestDiffSnapshotsUrl(t *testing.T) {
	fake, cleanup := jiritest.NewFakeJiriRoot(t)
	defer cleanup()

	s1, s2, d := setUpSnapshots(t, fake.X.Root)
	want, err := json.Marshal(d)
	if err != nil {
		t.Fatal(err)
	}

	serverMux := http.NewServeMux()
	serverMux.HandleFunc("/1", func(rw http.ResponseWriter, r *http.Request) {
		rw.Write(s1)
	})
	serverMux.HandleFunc("/2", func(rw http.ResponseWriter, r *http.Request) {
		rw.Write(s2)
	})
	server := httptest.NewServer(serverMux)
	defer server.Close()

	diff, err := getDiff(fake.X, server.URL+"/1", server.URL+"/2")
	if err != nil {
		t.Fatal(err)
	}
	got, err := json.Marshal(diff)
	if err != nil {
		t.Fatal(err)
	}
	if string(got) != string(want) {
		t.Fatalf("Error, got: %s\n\nwant:%s", got, want)
	}
}
