// 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 = new(Corpus)
	}
	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 := new(Corpus)
	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 := new(Corpus)
	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 := new(Corpus)
	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())
	}
}
