/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You 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 client

import (
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/api/meta"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/discovery"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/restmapper"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// FastMapperAllowedAPIGroups contains a set of API groups that are allowed when using the fastmapper.
// Those must correspond to all groups used by the "kamel" binary tool when running out-of-cluster.
var FastMapperAllowedAPIGroups = map[string]bool{
	"":                          true, // core APIs
	"apiextensions.k8s.io":      true,
	"apps":                      true,
	"batch":                     true,
	"camel.apache.org":          true,
	"rbac.authorization.k8s.io": true,
	"console.openshift.io":      true, // OpenShift console resources
	"operators.coreos.com":      true, // Operator SDK OLM
}

// newFastDiscoveryRESTMapper comes from https://github.com/kubernetes-sigs/controller-runtime/pull/592.
// We may leverage the controller-runtime bits in the future, if that gets merged upstream.
func newFastDiscoveryRESTMapper(config *rest.Config) meta.RESTMapper {
	return meta.NewLazyRESTMapperLoader(func() (meta.RESTMapper, error) {
		return newFastDiscoveryRESTMapperWithFilter(config, func(g *metav1.APIGroup) bool {
			return FastMapperAllowedAPIGroups[g.Name]
		})
	})
}

func newFastDiscoveryRESTMapperWithFilter(config *rest.Config, filter func(*metav1.APIGroup) bool) (meta.RESTMapper, error) {
	dc := discovery.NewDiscoveryClientForConfigOrDie(config)
	groups, err := dc.ServerGroups()
	if err != nil {
		return nil, err
	}
	wg := wait.Group{}
	totalCount := 0
	pickedCount := 0
	grs := make([]*restmapper.APIGroupResources, 0)
	for _, group := range groups.Groups {
		pinnedGroup := group
		pick := filter(&pinnedGroup)
		logrus.Debugf("Group: %s %v", group.Name, pick)
		totalCount++
		if !pick {
			continue
		}
		pickedCount++
		gr := &restmapper.APIGroupResources{
			Group:              group,
			VersionedResources: make(map[string][]metav1.APIResource),
		}
		grs = append(grs, gr)
		wg.Start(func() { discoverGroupResources(dc, gr) })
	}
	wg.Wait()
	logrus.Debugf("Picked %d/%d", pickedCount, totalCount)
	return restmapper.NewDiscoveryRESTMapper(grs), nil
}

func discoverGroupResources(dc discovery.DiscoveryInterface, gr *restmapper.APIGroupResources) {
	for _, version := range gr.Group.Versions {
		resources, err := dc.ServerResourcesForGroupVersion(version.GroupVersion)
		if err != nil {
			logrus.Fatal(err, version.GroupVersion)
		}
		gr.VersionedResources[version.Version] = resources.APIResources
	}
}
