// 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{}
	m2 := &project.Manifest{}
	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)
	}
}
