// 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 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())
	}
}
