/*
Copyright 2017 The Kubernetes 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 gce

import (
	"context"
	"fmt"
	"net/http"
	"path"

	compute "google.golang.org/api/compute/v1"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/klog"

	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter"
	"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
	cloudprovider "k8s.io/cloud-provider"
)

func newRoutesMetricContext(request string) *metricContext {
	return newGenericMetricContext("routes", request, unusedMetricLabel, unusedMetricLabel, computeV1Version)
}

// ListRoutes in the cloud environment.
func (g *Cloud) ListRoutes(ctx context.Context, clusterName string) ([]*cloudprovider.Route, error) {
	ctx, cancel := cloud.ContextWithCallTimeout()
	defer cancel()

	mc := newRoutesMetricContext("list")
	prefix := truncateClusterName(clusterName)
	f := filter.Regexp("name", prefix+"-.*").AndRegexp("network", g.NetworkURL()).AndRegexp("description", k8sNodeRouteTag)
	routes, err := g.c.Routes().List(ctx, f)
	if err != nil {
		return nil, mc.Observe(err)
	}
	var croutes []*cloudprovider.Route
	for _, r := range routes {
		target := path.Base(r.NextHopInstance)
		// TODO: Should we lastComponent(target) this?
		targetNodeName := types.NodeName(target) // NodeName == Instance Name on GCE
		croutes = append(croutes, &cloudprovider.Route{
			Name:            r.Name,
			TargetNode:      targetNodeName,
			DestinationCIDR: r.DestRange,
		})
	}
	return croutes, mc.Observe(nil)
}

// CreateRoute in the cloud environment.
func (g *Cloud) CreateRoute(ctx context.Context, clusterName string, nameHint string, route *cloudprovider.Route) error {
	ctx, cancel := cloud.ContextWithCallTimeout()
	defer cancel()

	mc := newRoutesMetricContext("create")

	targetInstance, err := g.getInstanceByName(mapNodeNameToInstanceName(route.TargetNode))
	if err != nil {
		return mc.Observe(err)
	}
	cr := &compute.Route{
		Name:            truncateClusterName(clusterName) + "-" + nameHint,
		DestRange:       route.DestinationCIDR,
		NextHopInstance: fmt.Sprintf("zones/%s/instances/%s", targetInstance.Zone, targetInstance.Name),
		Network:         g.NetworkURL(),
		Priority:        1000,
		Description:     k8sNodeRouteTag,
	}
	err = g.c.Routes().Insert(ctx, meta.GlobalKey(cr.Name), cr)
	if isHTTPErrorCode(err, http.StatusConflict) {
		klog.Infof("Route %q already exists.", cr.Name)
		err = nil
	}
	return mc.Observe(err)
}

// DeleteRoute from the cloud environment.
func (g *Cloud) DeleteRoute(ctx context.Context, clusterName string, route *cloudprovider.Route) error {
	ctx, cancel := cloud.ContextWithCallTimeout()
	defer cancel()

	mc := newRoutesMetricContext("delete")
	return mc.Observe(g.c.Routes().Delete(ctx, meta.GlobalKey(route.Name)))
}

func truncateClusterName(clusterName string) string {
	if len(clusterName) > 26 {
		return clusterName[:26]
	}
	return clusterName
}
