/*
 * Copyright 2019-2023 Open Networking Foundation (ONF) and the ONF Contributors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package order

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

type SortIncludedStruct struct {
	Seven string
}

type SortTestStruct struct {
	Id    int
	One   string
	Two   string
	Three uint
	Four  int
	Six   SortIncludedStruct
	Eight *SortIncludedStruct
}

var testSetOne = []SortTestStruct{
	{
		Id:    0,
		One:   "a",
		Two:   "x",
		Three: 10,
		Four:  1,
		Six:   SortIncludedStruct{Seven: "o"},
		Eight: &SortIncludedStruct{Seven: "o"},
	},
	{
		Id:    1,
		One:   "a",
		Two:   "c",
		Three: 1,
		Four:  10,
		Six:   SortIncludedStruct{Seven: "p"},
		Eight: &SortIncludedStruct{Seven: "p"},
	},
	{
		Id:    2,
		One:   "a",
		Two:   "b",
		Three: 2,
		Four:  1000,
		Six:   SortIncludedStruct{Seven: "q"},
		Eight: &SortIncludedStruct{Seven: "q"},
	},
	{
		Id:    3,
		One:   "a",
		Two:   "a",
		Three: 3,
		Four:  100,
		Six:   SortIncludedStruct{Seven: "r"},
		Eight: &SortIncludedStruct{Seven: "r"},
	},
	{
		Id:    4,
		One:   "b",
		Two:   "a",
		Three: 3,
		Four:  0,
		Six:   SortIncludedStruct{Seven: "s"},
		Eight: &SortIncludedStruct{Seven: "s"},
	},
}

var testSetTwo = []SortTestStruct{
	{
		Id:    0,
		One:   "a",
		Two:   "x",
		Three: 10,
		Four:  10,
	},
	{
		Id:    1,
		One:   "a",
		Two:   "y",
		Three: 1,
		Four:  1,
	},
}

func Verify(v []SortTestStruct, order []int) bool {
	for i, item := range v {
		if item.Id != order[i] {
			return false
		}
	}
	return true
}

func TestSort(t *testing.T) {
	s, err := Parse("+One,-Two")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 1, 2, 3, 4}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortASC(t *testing.T) {
	s, err := Parse("+One,Two")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetTwo)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 1}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortUintASC(t *testing.T) {
	s, err := Parse("Three,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{1, 2, 3, 4, 0}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortUintDSC(t *testing.T) {
	s, err := Parse("-Three,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 3, 4, 2, 1}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortUintDSC2(t *testing.T) {
	s, err := Parse("-Three,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetTwo)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 1}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortIntASC(t *testing.T) {
	s, err := Parse("Four,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}
	if !Verify(o.([]SortTestStruct), []int{4, 0, 1, 3, 2}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortIntDSC(t *testing.T) {
	s, err := Parse("-Four,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}
	if !Verify(o.([]SortTestStruct), []int{2, 3, 1, 0, 4}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortIntDSC2(t *testing.T) {
	s, err := Parse("-Four,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetTwo)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}
	if !Verify(o.([]SortTestStruct), []int{0, 1}) {
		t.Errorf("incorrect sort")
	}
}

func TestOperString(t *testing.T) {
	if ASC.String() != "ASC" {
		t.Errorf("ASC to string failed")
	}
	if DSC.String() != "DSC" {
		t.Errorf("DSC to string failed")
	}
	var o Operation = 5 // Invalid
	if o.String() != "ASC" {
		t.Errorf("to string default failed")
	}
}

func TestSortSingle(t *testing.T) {
	s, err := Parse("-Four,One")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne[0])
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if o == nil {
		t.Errorf("expected value, got nil")
	}

	r, ok := o.(SortTestStruct)
	if !ok {
		t.Errorf("Unexpected result type")
	}

	if r.Id != testSetOne[0].Id {
		t.Errorf("results don't match input")
	}
}

func TestSortDotted(t *testing.T) {
	s, err := Parse("+Six.Seven")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 1, 2, 3, 4}) {
		t.Errorf("incorrect sort")
	}
}

func TestSortDottedPointer(t *testing.T) {
	s, err := Parse("+Eight.Seven")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	if err != nil {
		t.Errorf("Sort failed: %s", err.Error())
	}

	if !Verify(o.([]SortTestStruct), []int{0, 1, 2, 3, 4}) {
		t.Errorf("incorrect sort")
	}
}

func TestInvalidDotted(t *testing.T) {
	s, err := Parse("+Six.Nonexistent")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	assert.EqualError(t, err, "Failed to find field Nonexistent while sorting")
	if o != nil {
		t.Errorf("expected no results, got some")
	}
}

func TestDotOnString(t *testing.T) {
	s, err := Parse("+One.IsNotAStruct")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	assert.EqualError(t, err, "Dotted field name specified in filter did not resolve to a valid field")
	if o != nil {
		t.Errorf("expected no results, got some")
	}
}

func TestSortOnStuct(t *testing.T) {
	s, err := Parse("+Six")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	assert.EqualError(t, err, "Cannot sort on a field that is a struct")
	if o != nil {
		t.Errorf("expected no results, got some")
	}
}

func TestSortOnPointerStuct(t *testing.T) {
	s, err := Parse("+Eight")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	assert.EqualError(t, err, "Cannot sort on a field that is a struct")
	if o != nil {
		t.Errorf("expected no results, got some")
	}
}

func TestTrailingDot(t *testing.T) {
	s, err := Parse("+Six.Seven.")
	if err != nil {
		t.Errorf("Unable to parse sort specification")
	}
	o, err := s.Process(testSetOne)
	assert.EqualError(t, err, "Dotted field name specified in filter did not resolve to a valid field")
	if o != nil {
		t.Errorf("expected no results, got some")
	}
}
