// Copyright 2017 The Go 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 maintner

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"testing"
	"time"

	"github.com/davecgh/go-spew/spew"
	"github.com/golang/protobuf/ptypes"
	google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
	"github.com/google/go-github/github"
	"golang.org/x/build/maintner/maintpb"
)

var u1 = &GitHubUser{
	Login: "gopherbot",
	ID:    100,
}
var u2 = &GitHubUser{
	Login: "kevinburke",
	ID:    101,
}

type dummyMutationLogger struct {
	Mutations []*maintpb.Mutation
}

func (d *dummyMutationLogger) Log(m *maintpb.Mutation) error {
	if d.Mutations == nil {
		d.Mutations = []*maintpb.Mutation{}
	}
	d.Mutations = append(d.Mutations, m)
	return nil
}

type mutationTest struct {
	corpus *Corpus
	want   *Corpus
}

func (mt mutationTest) test(t *testing.T, muts ...*maintpb.Mutation) {
	c := mt.corpus
	if c == nil {
		c = NewCorpus(&dummyMutationLogger{}, "")
	}
	for _, m := range muts {
		c.processMutationLocked(m)
	}
	c.github.c = nil
	mt.want.github.c = nil
	if !reflect.DeepEqual(c.github, mt.want.github) {
		t.Errorf("corpus mismatch:\n got: %s\n\nwant: %s\n\ndiff: %v",
			spew.Sdump(c.github),
			spew.Sdump(mt.want.github),
			diffPath(reflect.ValueOf(c.github), reflect.ValueOf(mt.want.github)))
	}
}

var t1, t2 time.Time
var tp1, tp2 *google_protobuf.Timestamp

func init() {
	t1, _ = time.Parse(time.RFC3339, "2016-01-02T15:04:00Z")
	t2, _ = time.Parse(time.RFC3339, "2016-01-02T15:30:00Z")
	tp1, _ = ptypes.TimestampProto(t1)
	tp2, _ = ptypes.TimestampProto(t2)
}

func TestProcessMutation_Github_NewIssue(t *testing.T) {
	c := NewCorpus(&dummyMutationLogger{}, "")
	github := &GitHub{c: c}
	c.github = github
	github.users = map[int64]*GitHubUser{
		u1.ID: u1,
	}
	github.repos = map[GithubRepoID]*GitHubRepo{
		GithubRepoID{"golang", "go"}: &GitHubRepo{
			github: github,
			id:     GithubRepoID{"golang", "go"},
			issues: map[int32]*GitHubIssue{
				3: &GitHubIssue{
					Number:    3,
					User:      u1,
					Title:     "some title",
					Body:      "some body",
					Created:   t1,
					Assignees: nil,
				},
			},
		},
	}
	mutationTest{want: c}.test(t, &maintpb.Mutation{
		GithubIssue: &maintpb.GithubIssueMutation{
			Owner:  "golang",
			Repo:   "go",
			Number: 3,
			User: &maintpb.GithubUser{
				Login: "gopherbot",
				Id:    100,
			},
			Title:   "some title",
			Body:    "some body",
			Created: tp1,
		},
	})
}

func TestProcessMutation_Github(t *testing.T) {
	c := NewCorpus(&dummyMutationLogger{}, "")
	github := &GitHub{c: c}
	c.github = github
	github.repos = map[GithubRepoID]*GitHubRepo{
		GithubRepoID{"golang", "go"}: &GitHubRepo{
			github: github,
			id:     GithubRepoID{"golang", "go"},
			issues: make(map[int32]*GitHubIssue),
		},
	}
	mutationTest{want: c}.test(t, &maintpb.Mutation{
		Github: &maintpb.GithubMutation{
			Owner: "golang",
			Repo:  "go",
		},
	})
}

func TestNewMutationsFromIssue(t *testing.T) {
	gh := &github.Issue{
		Number:    github.Int(5),
		CreatedAt: &t1,
		UpdatedAt: &t2,
		Body:      github.String("body of the issue"),
		State:     github.String("closed"),
	}
	gr := &GitHubRepo{
		id: GithubRepoID{"golang", "go"},
	}
	is := gr.newMutationFromIssue(nil, gh)
	want := &maintpb.Mutation{GithubIssue: &maintpb.GithubIssueMutation{
		Owner:       "golang",
		Repo:        "go",
		Number:      5,
		Body:        "body of the issue",
		Created:     tp1,
		Updated:     tp2,
		Assignees:   []*maintpb.GithubUser{},
		NoMilestone: true,
		Closed:      &maintpb.BoolChange{Val: true},
	}}
	if !reflect.DeepEqual(is, want) {
		t.Errorf("issue mismatch\n got: %v\nwant: %v\ndiff path: %v", spew.Sdump(is), spew.Sdump(want),
			diffPath(reflect.ValueOf(is), reflect.ValueOf(want)))
	}
}

func TestNewAssigneesHandlesNil(t *testing.T) {
	users := []*github.User{
		&github.User{Login: github.String("foo"), ID: github.Int(3)},
	}
	got := newAssignees(nil, users)
	want := []*maintpb.GithubUser{&maintpb.GithubUser{
		Id:    3,
		Login: "foo",
	}}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("assignee mismatch\n got: %#v\nwant: %#v", got, want)
	}
}

func TestAssigneesDeleted(t *testing.T) {
	c := NewCorpus(&dummyMutationLogger{}, "")
	assignees := []*GitHubUser{u1, u2}
	issue := &GitHubIssue{
		Number:    3,
		User:      u1,
		Body:      "some body",
		Created:   t2,
		Updated:   t2,
		Assignees: assignees,
	}
	gr := &GitHubRepo{
		id: GithubRepoID{"golang", "go"},
		issues: map[int32]*GitHubIssue{
			3: issue,
		},
	}
	c.github = &GitHub{
		users: map[int64]*GitHubUser{
			u1.ID: u1,
		},
		repos: map[GithubRepoID]*GitHubRepo{
			GithubRepoID{"golang", "go"}: gr,
		},
	}

	mutation := gr.newMutationFromIssue(issue, &github.Issue{
		Number:    github.Int(3),
		Assignees: []*github.User{&github.User{ID: github.Int(int(u2.ID))}},
	})
	c.addMutation(mutation)
	gi := gr.issues[3]
	if len(gi.Assignees) != 1 || gi.Assignees[0].ID != u2.ID {
		t.Errorf("expected u1 to be deleted, got %v", gi.Assignees)
	}
}

func DeepDiff(got, want interface{}) error {
	return diffPath(reflect.ValueOf(got), reflect.ValueOf(want))
}

func diffPath(got, want reflect.Value) error {
	if !got.IsValid() {
		return errors.New("'got' value invalid")
	}
	if !want.IsValid() {
		return errors.New("'want' value invalid")
	}

	t := got.Type()
	if t != want.Type() {
		return fmt.Errorf("got=%s, want=%s", got.Type(), want.Type())
	}

	switch t.Kind() {
	case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
		if got.IsNil() != want.IsNil() {
			if got.IsNil() {
				return fmt.Errorf("got = (%s)(nil), want = non-nil", t)
			}
			return fmt.Errorf("got = (%s)(non-nil), want = nil", t)
		}
	}

	switch t.Kind() {
	case reflect.Ptr:
		if got.IsNil() {
			return nil
		}
		return diffPath(got.Elem(), want.Elem())

	case reflect.Struct:
		nf := t.NumField()
		for i := 0; i < nf; i++ {
			sf := t.Field(i)
			if err := diffPath(got.Field(i), want.Field(i)); err != nil {
				inner := err.Error()
				sep := "."
				if strings.HasPrefix(inner, "field ") {
					inner = strings.TrimPrefix(inner, "field ")
				} else {
					sep = ": "
				}
				return fmt.Errorf("field %s%s%v", sf.Name, sep, inner)
			}
		}
		return nil
	case reflect.String:
		if got.String() != want.String() {
			return fmt.Errorf("got = %q; want = %q", got.String(), want.String())
		}
		return nil

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if got.Int() != want.Int() {
			return fmt.Errorf("got = %v; want = %v", got.Int(), want.Int())
		}
		return nil

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if got.Uint() != want.Uint() {
			return fmt.Errorf("got = %v; want = %v", got.Uint(), want.Uint())
		}
		return nil

	case reflect.Bool:
		if got.Bool() != want.Bool() {
			return fmt.Errorf("got = %v; want = %v", got.Bool(), want.Bool())
		}
		return nil

	case reflect.Slice:
		gl, wl := got.Len(), want.Len()
		if gl != wl {
			return fmt.Errorf("slice len %v; want %v", gl, wl)
		}
		for i := 0; i < gl; i++ {
			if err := diffPath(got.Index(i), want.Index(i)); err != nil {
				return fmt.Errorf("index[%d] differs: %v", i, err)
			}
		}
		return nil

	default:
		return fmt.Errorf("unhandled kind %v", t.Kind())
	}
}
