package orm

import (
	"testing"
	"time"

	"github.com/jinzhu/gorm"
	"github.com/remogatto/prettytest"
)

type testSuite struct {
	prettytest.Suite
}

func TestRunner(t *testing.T) {
	prettytest.Run(
		t,
		new(testSuite),
	)
}

func (t *testSuite) BeforeAll() {
	var (
		db  *gorm.DB
		err error
	)

	connected := false
	for !connected {
		time.Sleep(10 * time.Second)
		db, err = New("karmen:karmen@/karmen_test?charset=utf8&parseTime=True&loc=Local")
		if err != nil {
			time.Sleep(5 * time.Second)
			continue
		}
		connected = true
	}

	Use(db)
	AutoMigrate()
}

func (t *testSuite) TestDB() {
	t.Not(t.Nil(DB()))
}

func (t *testSuite) TestGetTeachers() {
	teachers, err := GetTeachers()
	t.Nil(err)
	t.Equal(9, len(teachers))

	teacher := teachers[0]
	classes, err := teacher.GetClasses()
	t.Nil(err)
	t.Equal(1, len(classes))
	t.Equal(1, len(teacher.Classes))

	class := classes[0]
	t.Equal("1 A", class.Name)
}

// func (t *testSuite) Before() {
// 	var activities []Activity
// 	if err := DB().Find(&activities).Error; err != nil {
// 		panic(err)
// 	}
// 	for _, a := range activities {
// 		DB().Unscoped().Delete(&a)
// 	}

// 	if err := DB().Exec("ALTER TABLE activities AUTO_INCREMENT = 1").Error; err != nil {
// 		panic(err)
// 	}
// }

// func (t *testSuite) TestCredential() {
// 	var teacher Teacher

// 	teacher.Name = "John"
// 	teacher.Surname = "Doe"

// 	if err := DB().Create(&teacher).Error; err != nil {
// 		panic(err)
// 	}

// 	if err := DB().Find(&teacher).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(teacher.Username, "john.doe")
// 	t.Equal(teacher.Email, "john.doe@foo.org")
// 	t.Equal(teacher.Password, "RKDb/GzQw8jzfAFwiAjclA81oBtzYWx0")
// }

// func (t *testSuite) TestCreateUpdateActivity() {
// 	var (
// 		class   Class
// 		subject Subject
// 	)

// 	activity := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	// Activity 1
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher := Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	// 1A
// 	if err := DB().Find(&class, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	// Italiano
// 	if err := DB().Find(&subject, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(5, teacher.CurrHours)
// 	t.Equal("1A", teacher.Classes[0].Name)
// 	t.Equal("Italiano", teacher.Subjects[0].Name)

// 	// Add another activity and check for teacher's hours, subjects and classes

// 	// Subject: "Latino"
// 	// Class: "1B"
// 	activity = Activity{Hours: 3, TeacherID: 1, ClassID: 2, SubjectID: 2}

// 	// Activity 2
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher = Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(8, teacher.CurrHours)
// 	t.Equal("1A", teacher.Classes[0].Name)
// 	t.Equal("1B", teacher.Classes[1].Name)
// 	t.Equal("Italiano", teacher.Subjects[0].Name)
// 	t.Equal("Latino", teacher.Subjects[1].Name)

// 	// Add an activity without teacher

// 	// Subject: "Latino"
// 	// Class: "2A"
// 	activity = Activity{Hours: 3, TeacherID: 0, ClassID: 3, SubjectID: 2}

// 	// Activity 3
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Test update activty

// 	activity = Activity{}
// 	if err := DB().Find(&activity, 1).Error; err != nil {
// 		panic(err)
// 	}
// 	activity.Hours = 4

// 	if err := DB().Save(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher = Teacher{}
// 	if err := DB().Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(7, teacher.CurrHours)

// 	// Delete an activity and check for the right number of hours and associations

// 	if err := DB().Delete(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher = Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(3, teacher.CurrHours)
// 	t.Equal(1, len(teacher.Classes))
// 	t.Equal(1, len(teacher.Subjects))
// 	t.Equal("1B", teacher.Classes[0].Name)
// 	t.Equal("Latino", teacher.Subjects[0].Name)

// 	// Remove teacher from activity and check for consistency

// 	activity = Activity{}
// 	teacher = Teacher{}
// 	if err := DB().Find(&activity, 2).Error; err != nil {
// 		panic(err)
// 	}
// 	activity.TeacherID = 0

// 	if err := DB().Save(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(0, teacher.CurrHours)
// 	t.Equal(0, len(teacher.Classes))
// 	t.Equal(0, len(teacher.Subjects))

// 	// Change teacher in activity and check for consistency

// 	// Subject: "Latino"
// 	// Class: "1B"
// 	activity = Activity{Hours: 3, TeacherID: 1, ClassID: 2, SubjectID: 2}

// 	// Activity 3
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}
// 	activity.TeacherID = 2

// 	if err := DB().Save(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher = Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.Equal(0, teacher.CurrHours)
// 	t.Equal(0, len(teacher.Classes))
// 	t.Equal(0, len(teacher.Subjects))

// }

// func (t *testSuite) TestClassTeachers() {
// 	var class Class

// 	activity_1 := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	if err := DB().Create(&activity_1).Error; err != nil {
// 		panic(err)
// 	}

// 	activity_2 := Activity{Hours: 3, TeacherID: 1, ClassID: 2, SubjectID: 2}

// 	if err := DB().Create(&activity_2).Error; err != nil {
// 		panic(err)
// 	}

// 	if err := DB().Preload("Teachers").First(&class, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	subjects := class.Teachers[0].GetSubjectsByClassID(class.ID)
// 	t.Equal(1, len(subjects))
// 	t.Equal("Italiano", subjects[0].Name)

// }

// func (t *testSuite) TestCoordinatorMinuter() {
// 	var (
// 		class     Class
// 		teacher_1 Teacher
// 		teacher_2 Teacher
// 	)

// 	activity_1 := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	if err := DB().Create(&activity_1).Error; err != nil {
// 		panic(err)
// 	}

// 	activity_2 := Activity{Hours: 5, TeacherID: 2, ClassID: 1, SubjectID: 1}

// 	if err := DB().Create(&activity_2).Error; err != nil {
// 		panic(err)
// 	}

// 	if err := DB().First(&class, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	class.CoordinatorID = 1
// 	class.MinuterID = 2

// 	if err := DB().Save(&class).Error; err != nil {
// 		panic(err)
// 	}

// 	if err := DB().Find(&teacher_1, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	if err := DB().Find(&teacher_2, 2).Error; err != nil {
// 		panic(err)
// 	}

// 	classes_1 := teacher_1.IsCoordinator()
// 	t.Equal(1, len(classes_1))

// 	if len(classes_1) > 0 {
// 		t.Equal("1A", classes_1[0].Name)
// 	}

// 	classes_2 := teacher_2.IsMinuter()
// 	t.Equal(1, len(classes_2))

// 	if len(classes_2) > 0 {
// 		t.Equal("1A", classes_2[0].Name)
// 	}

// }

// func (t *testSuite) TestTeacherHasClass() {
// 	activity := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	// Activity 1
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher := Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.True(teacher.HasClass("1A"))
// }

// func (t *testSuite) TestTeacherHasSubject() {
// 	activity := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	// Activity 1
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher := Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.True(teacher.HasSubject("Italiano"))
// }

// func (t *testSuite) TestTeacherHasSubjectInClass() {
// 	activity := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	// Activity 1
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	// Marco Rossi
// 	teacher := Teacher{}
// 	if err := DB().Preload("Classes").Preload("Subjects").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.True(teacher.HasSubjectInClass("Italiano", "1A"))
// }

// func (t *testSuite) TestTeacherIsCoordinatorInClass() {
// 	activity := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}

// 	// Activity 1
// 	if err := DB().Create(&activity).Error; err != nil {
// 		panic(err)
// 	}

// 	var class Class

// 	if err := DB().First(&class, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	class.CoordinatorID = 1

// 	// Marco Rossi
// 	teacher := Teacher{}
// 	if err := DB().Preload("Classes").Find(&teacher, 1).Error; err != nil {
// 		panic(err)
// 	}

// 	t.True(teacher.IsCoordinatorInClass("1A"))
// }

// func (t *testSuite) TestTeacherIssues() {
// 	// activity_1 := Activity{Hours: 5, TeacherID: 1, ClassID: 1, SubjectID: 1}
// 	// activity_2 := Activity{Hours: 10, TeacherID: 1, ClassID: 2, SubjectID: 1}

// 	// if err := DB().Create(&activity_1).Error; err != nil {
// 	// 	panic(err)
// 	// }

// 	// if err := DB().Create(&activity_2).Error; err != nil {
// 	// 	panic(err)
// 	// }

// 	// // Marco Rossi
// 	// teacher := Teacher{}
// 	// if err := DB().Preload("Issues").Find(&teacher, 1).Error; err != nil {
// 	// 	panic(err)
// 	// }

// 	// t.Equal(1, len(teacher.Issues))
// 	// t.Equal(IssueTeacherHours, teacher.Issues[0].Type)
// }
