// Copyright 2017 The kubecfg authors
//
//
//    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 utils

import (
	"path/filepath"
	"reflect"
	"sort"
	"testing"

	openapi_v2 "github.com/google/gnostic/openapiv2"
	log "github.com/sirupsen/logrus"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/client-go/discovery"
	fakedisco "k8s.io/client-go/discovery/fake"
	"k8s.io/client-go/restmapper"
	ktesting "k8s.io/client-go/testing"
)

type FakeDiscovery struct {
	fakedisco.FakeDiscovery
	schemaGetter discovery.OpenAPISchemaInterface
}

func NewFakeDiscovery(schemaGetter discovery.OpenAPISchemaInterface) *FakeDiscovery {
	fakePtr := &ktesting.Fake{}
	return &FakeDiscovery{
		FakeDiscovery: fakedisco.FakeDiscovery{Fake: fakePtr},
		schemaGetter:  schemaGetter,
	}
}

func (c *FakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) {
	action := ktesting.ActionImpl{}
	action.Verb = "get"
	c.Fake.Invokes(action, nil)

	return c.schemaGetter.OpenAPISchema()
}

func TestDepSort(t *testing.T) {
	t.Skip("Skip test broken by kartongips fork.")
	log.SetLevel(log.DebugLevel)

	disco := NewFakeDiscovery(schemaFromFile{dir: filepath.FromSlash("../testdata")})
	disco.Resources = []*metav1.APIResourceList{
		{
			GroupVersion: "v1",
			APIResources: []metav1.APIResource{
				{
					Name:       "configmaps",
					Kind:       "ConfigMap",
					Namespaced: true,
				},
				{
					Name:       "namespaces",
					Kind:       "Namespace",
					Namespaced: false,
				},
				{
					Name:       "replicationcontrollers",
					Kind:       "ReplicationController",
					Namespaced: true,
				},
			},
		},
	}

	mapper := restmapper.NewDiscoveryRESTMapper([]*restmapper.APIGroupResources{{
		Group: metav1.APIGroup{
			Name: "",
			Versions: []metav1.GroupVersionForDiscovery{{
				GroupVersion: "v1",
				Version:      "v1",
			}},
		},
		VersionedResources: map[string][]metav1.APIResource{
			"v1": disco.Resources[0].APIResources,
		},
	}})

	newObj := func(apiVersion, kind string) *unstructured.Unstructured {
		return &unstructured.Unstructured{
			Object: map[string]interface{}{
				"apiVersion": apiVersion,
				"kind":       kind,
			},
		}
	}

	objs := []*unstructured.Unstructured{
		newObj("v1", "ReplicationController"),
		newObj("v1", "ConfigMap"),
		newObj("v1", "Namespace"),
		newObj("admissionregistration.k8s.io/v1beta1", "MutatingWebhookConfiguration"),
		newObj("bogus/v1", "UnknownKind"),
		newObj("apiextensions.k8s.io/v1beta1", "CustomResourceDefinition"),
	}

	sorter, err := DependencyOrder(disco, mapper, objs)
	if err != nil {
		t.Fatalf("DependencyOrder error: %v", err)
	}
	sort.Sort(sorter)

	for i, o := range objs {
		t.Logf("obj[%d] after sort is %v", i, o.GroupVersionKind())
	}

	if objs[0].GetKind() != "CustomResourceDefinition" {
		t.Error("CRD should be sorted first")
	}
	if objs[1].GetKind() != "Namespace" {
		t.Error("Namespace should be sorted second")
	}
	if objs[4].GetKind() != "ReplicationController" {
		t.Error("RC should be sorted after non-pod objects")
	}
	if objs[5].GetKind() != "MutatingWebhookConfiguration" {
		t.Error("Webhook should be sorted last")
	}
}

func TestAlphaSort(t *testing.T) {
	newObj := func(ns, name, kind string) *unstructured.Unstructured {
		o := unstructured.Unstructured{}
		o.SetNamespace(ns)
		o.SetName(name)
		o.SetKind(kind)
		return &o
	}

	objs := []*unstructured.Unstructured{
		newObj("default", "mysvc", "Deployment"),
		newObj("", "default", "StorageClass"),
		newObj("", "default", "ClusterRole"),
		newObj("default", "mydeploy", "Deployment"),
		newObj("default", "mysvc", "Secret"),
	}

	expected := []*unstructured.Unstructured{
		objs[2],
		objs[1],
		objs[3],
		objs[0],
		objs[4],
	}

	sort.Sort(AlphabeticalOrder(objs))

	if !reflect.DeepEqual(objs, expected) {
		t.Errorf("actual != expected: %v != %v", objs, expected)
	}
}
