package rules

import (
	"encoding/json"
	"testing"
)

func TestIncidentActionType(t *testing.T) {
	var action IncidentAction

	if action.GetType() != IncidentActionType {
		t.Errorf("Bad action type: %v", action.GetType())
	}
}

func TestMarshall(t *testing.T) {
	action := IncidentAction{
		Title:                "Test2",
		Comment:              "Test3",
		Effects:              make([]string, 2),
		Category:             "14",
		Importance:           "90",
		Assigned:             "3",
		Description:          "Test7",
		CloseRecommendations: make([]string, 2),
	}

	action.Effects[0] = "3"
	action.Effects[1] = "2"
	action.CloseRecommendations[0] = "7"
	action.CloseRecommendations[1] = "15"

	bytes, err := json.Marshal(action)
	if err != nil {
		t.Errorf("Got error: %v", err)
	}

	if string(bytes) != `{"assigned_to":3,"category":14,"close_recommendations":[7,15],"comment":"Test3","description":"Test7","effects":[3,2],"importance":90,"title":"Test2"}` {
		t.Errorf("Got bad json: %v", string(bytes))
	}
}

func TestUnmarshall(t *testing.T) {
	str := `{"type":"incident","title":"Veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong incident title",
             "comment":"Test3","effects":["3","2"],"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":["7","15"]}`

	var action IncidentAction
	err := json.Unmarshal([]byte(str), &action)
	if err != nil {
		t.Errorf("Can't unmarshall json: %v", err)
	}

	if action.GetType() != IncidentActionType {
		t.Errorf("Bad action type: %v", action.GetType())
	}

	if action.Title != "Veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeery looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong incident title" {
		t.Errorf("Bad action title: %v", action.Title)
	}
	if len(action.Title) > 256 {
		t.Errorf("Title is bigger then 256")
	}

	if len(action.Effects) != 2 {
		t.Errorf("Bad effects size: %v", len(action.Effects))
	}

	if action.Effects[0] != "3" {
		t.Errorf("Bad effect #0: %v", action.Effects[0])
	}

	if action.Effects[1] != "2" {
		t.Errorf("Bad effect #1: %v", action.Effects[1])
	}

	if action.Category != "Test4" {
		t.Errorf("Bad category: %v", action.Category)
	}

	if action.Importance != "Test5" {
		t.Errorf("Bad importance: %v", action.Importance)
	}

	if action.Assigned != "Test6" {
		t.Errorf("Bad assigned value: %v", action.Assigned)
	}

	if action.Description != "Test7" {
		t.Errorf("Bad description: %v", action.Description)
	}

	if len(action.CloseRecommendations) != 2 {
		t.Errorf("Bad close reocmendation len: %v", len(action.CloseRecommendations))
	}

	if action.CloseRecommendations[0] != "7" {
		t.Errorf("Bad close recomendation #0: %v", action.CloseRecommendations[0])
	}

	if action.CloseRecommendations[1] != "15" {
		t.Errorf("Bad close recomendation #1: %v", action.CloseRecommendations[1])
	}
}

func TestBadUnmarshall(t *testing.T) {
	str := `{"type":"test","url":"Test1","title":"Test2","comment":"Test3","effects":["3","2"],"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":["7","15"]}`

	var action IncidentAction
	err := json.Unmarshal([]byte(str), &action)
	if err == nil {
		t.Errorf("Can read bad json: %v", action)
	}

}

func TestBadUnmarshall2(t *testing.T) {
	str := `jhgfghjk`

	var action IncidentAction
	err := json.Unmarshal([]byte(str), &action)
	if err == nil {
		t.Errorf("Can read bad json: %v", action)
	}
}

func TestParseInterface(t *testing.T) {
	str := `{"type":"incident","title":"Test2","comment":"Test3","effects":["3","2"],"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":["7","15"]}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err != nil {
		t.Errorf("Can't parse interface: %v", err)
	}

	if action.GetType() != IncidentActionType {
		t.Errorf("Bad action type: %v", action.GetType())
	}

	if action.Title != "Test2" {
		t.Errorf("Bad action title: %v", action.Title)
	}

	if len(action.Effects) != 2 {
		t.Errorf("Bad effects size: %v", len(action.Effects))
	}

	if action.Effects[0] != "3" {
		t.Errorf("Bad effect #0: %v", action.Effects[0])
	}

	if action.Effects[1] != "2" {
		t.Errorf("Bad effect #1: %v", action.Effects[1])
	}

	if action.Category != "Test4" {
		t.Errorf("Bad category: %v", action.Category)
	}

	if action.Importance != "Test5" {
		t.Errorf("Bad importance: %v", action.Importance)
	}

	if action.Assigned != "Test6" {
		t.Errorf("Bad assigned value: %v", action.Assigned)
	}

	if action.Description != "Test7" {
		t.Errorf("Bad description: %v", action.Description)
	}

	if len(action.CloseRecommendations) != 2 {
		t.Errorf("Bad close reocmendation len: %v", len(action.CloseRecommendations))
	}

	if action.CloseRecommendations[0] != "7" {
		t.Errorf("Bad close recomendation #0: %v", action.CloseRecommendations[0])
	}

	if action.CloseRecommendations[1] != "15" {
		t.Errorf("Bad close recomendation #1: %v", action.CloseRecommendations[1])
	}
}

func TestParseInterfaceWithSingleArrayValue(t *testing.T) {
	str := `{"type":"incident","title":"Test2","comment":"Test3","effects":"3","category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err != nil {
		t.Errorf("Can't parse interface: %v", err)
	}

	if action.GetType() != IncidentActionType {
		t.Errorf("Bad action type: %v", action.GetType())
	}

	if action.Title != "Test2" {
		t.Errorf("Bad action title: %v", action.Title)
	}

	if len(action.Effects) != 1 {
		t.Errorf("Bad effects size: %v", len(action.Effects))
	}

	if action.Effects[0] != "3" {
		t.Errorf("Bad effect #0: %v", action.Effects[0])
	}

	if action.Category != "Test4" {
		t.Errorf("Bad category: %v", action.Category)
	}

	if action.Importance != "Test5" {
		t.Errorf("Bad importance: %v", action.Importance)
	}

	if action.Assigned != "Test6" {
		t.Errorf("Bad assigned value: %v", action.Assigned)
	}

	if action.Description != "Test7" {
		t.Errorf("Bad description: %v", action.Description)
	}

	if len(action.CloseRecommendations) != 1 {
		t.Errorf("Bad close reocmendation len: %v", len(action.CloseRecommendations))
	}

	if action.CloseRecommendations[0] != "7" {
		t.Errorf("Bad close recomendation #0: %v", action.CloseRecommendations[0])
	}
}

func TestParseInterfaceWithIntArrayValue(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":3,"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err != nil {
		t.Errorf("Can't parse interface: %v", err)
	}

	if len(action.Effects) != 1 {
		t.Errorf("Bad effects size: %v", len(action.Effects))
	}

	if action.Effects[0] != "3" {
		t.Errorf("Bad effects #0 value: %v", action.Effects[0])
	}
}

func TestParseInterfaceWithIntArrayValue2(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":3,"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":7}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err != nil {
		t.Errorf("Can't parse interface: %v", err)
	}

	if len(action.CloseRecommendations) != 1 {
		t.Errorf("Bad close recommendations size: %v", len(action.CloseRecommendations))
	}

	if action.CloseRecommendations[0] != "7" {
		t.Errorf("Bad close recommendations #0 value: %v", action.CloseRecommendations[0])
	}
}

func TestParseInterfaceWithIntArrayValue3(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":3,"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":[7]}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err != nil {
		t.Errorf("Can't parse interface: %v", err)
	}

	if len(action.CloseRecommendations) != 1 {
		t.Errorf("Bad close recommendations size: %v", len(action.CloseRecommendations))
	}

	if action.CloseRecommendations[0] != "7" {
		t.Errorf("Bad close recommendations #0 value: %v", action.CloseRecommendations[0])
	}
}

func TestParseInterfaceBadInput1(t *testing.T) {
	str := `[1, 2, 3]`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput2(t *testing.T) {
	str := `{"type":"incident","comment":"Test3","effects":"3","category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput3(t *testing.T) {
	str := `{"type":"incident","url":"Test1","comment":"Test3","effects":"3","category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput4(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":{"test":"true"},"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput5(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":[1, 2, 3],"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":{"test":"true"}}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput6(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":[{"test":"test"}],"category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput7(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":"7","category":"Test4","importance":"Test5","assigned_to":"Test6","description":"Test7","close_recommendations":[{"test":"test"}]}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}

func TestParseInterfaceBadInput8(t *testing.T) {
	str := `{"type":"incident","url":"Test1","title":"Test2","comment":"Test3","effects":"3","category":"Test4","assigned_to":"Test6","description":"Test7","close_recommendations":"7"}`
	var action IncidentAction
	var i interface{}

	err := json.Unmarshal([]byte(str), &i)
	if err != nil {
		t.Errorf("Got error parsing json: %v", err)
	}

	err = action.ParseInterface(i)
	if err == nil {
		t.Errorf("Can parse bad interface: %v", i)
	}
}
