// Copyright 2021 Google LLC
//
// 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 configfetcher

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"
	"time"

	"policy-manager/protos"

	metadataServer "cloud.google.com/go/compute/metadata"
	"github.com/golang/glog"
	"github.com/golang/protobuf/jsonpb"
	"github.com/golang/protobuf/proto"
)

const (
	// gciLegacyConfigKey is the GCE metadata Key used to specify user's preference of
	// the InstanceConfig. The value of this key should be JSON representation
	// of the InstanceConfig proto.
	// DEPRECATED. Use the specific keys below.
	gciLegacyConfigKey = "gci-instance-config"

	// Metadata keys for each InstanceConfig attribute that users can specify.
	// Although we continue supporting metadata key with 'gci-' prefix, users
	// should use the keys with 'cos-' prefix if possible.
	gciKeyUpdateStrategy = "gci-update-strategy"
	gciKeyMetricsEnabled = "gci-metrics-enabled"

	// Metadata keys with 'cos-' prefix
	cosKeyUpdateStrategy = "cos-update-strategy"
	cosKeyMetricsEnabled = "cos-metrics-enabled"

	// Metadata keys for GCP-related features.
	keyGoogleLoggingEnabled    = "google-logging-enabled"
	keyGoogleMonitoringEnabled = "google-monitoring-enabled"

	// Note that there are 2 types of metadata entries: endpoint and
	// directory. Endpoint maps to a single value, while directory contains
	// a list of key value pairs.
	// URL path for metadata directory. Note that the trailing slash
	// indicates that the entry is a directory instead of an endpoint.
	// Without it the request will just be forwared by the metadata
	// server with a 301 status code.
	// The leading slash is required since these entries are relative to the
	// metadata server URL of the form http://.../...
	instanceCustomDataDirectory = "/instance/attributes/"
	projectCustomDataDirectory  = "/project/attributes/"

	// The sleep time when watching user config failed.
	retryInterval = 5 * time.Second
)

type mtd struct {
	metadata map[string]string
	etag     string
	err      error
}

// PollUserConfig watches the update of the InstanceConfig specified by user in GCE
// metadata. It repeatedly sends request to wait for update of userConfig. When an update
// is returned, PollUserConfig compares it to the cached userConfig and outputs to the
// channel if it is really updated.
func PollUserConfig(out chan *protos.InstanceConfig, gceMetadataURL string) {
	var userConfig, lastUserConfig *protos.InstanceConfig
	var err error
	var instanceEtag, projectEtag string
	lastUserConfig = nil
	for {
		userConfig, instanceEtag, projectEtag, err = getUserConfig(instanceEtag, projectEtag, gceMetadataURL)
		if err != nil {
			time.Sleep(retryInterval)
			instanceEtag = ""
			projectEtag = ""
			continue // Retry forever.
		}
		// Check whether userConfig is updated.
		if proto.Equal(lastUserConfig, userConfig) {
			glog.V(1).Infof(
				"Instance custom metadata are updated but instanceConfig stays the same: {%+v}",
				userConfig)
			continue
		}
		// To cache the original userConfig, a deep copy is necessary.
		lastUserConfig = proto.Clone(userConfig).(*protos.InstanceConfig)
		out <- userConfig
	}
}

// fetchMetadataTag gets the content of the metadata from the metadata
// server and parses the raw content. It then returns metadata as a
// map and etag value.
func fetchMetadataTag(ctx context.Context, lastEtag string, dataDirectory string, gceMetadataURL string) (map[string]string, string, error) {
	rawMetadata, etag, err := FetchMetadata(ctx, lastEtag, dataDirectory, gceMetadataURL)
	if err != nil {
		return nil, "", err
	}

	mtd, err := parseRawMetadata(rawMetadata)
	if err != nil {
		return nil, "", err
	}
	return mtd, etag, nil
}

// fetchMetadataWithChannel gets the content of the metadata from
// either instance or project and then writes the result to a channel.
func fetchMetadataWithChannel(ctx context.Context, lastEtag string, dataDirectory string, gceMetadataURL string, c chan<- mtd) {
	metadata, etag, err := fetchMetadataTag(ctx, lastEtag, dataDirectory, gceMetadataURL)
	if err != nil {
		c <- mtd{nil, "", err}
		return
	}
	c <- mtd{metadata, etag, nil}
}

// getUserConfig gets the content of the instance and project custom
// metadata keys. Then getUserConfig parses the metadata keys and
// returns userConfig.
func getUserConfig(lastInstanceEtag string, lastProjectEtag string, gceMetadataURL string) (*protos.InstanceConfig, string, string, error) {
	var instanceMetadata, projectMetadata map[string]string
	var instanceEtag, projectEtag string
	var err error
	instanceChannel := make(chan mtd, 1)
	projectChannel := make(chan mtd, 1)

	ctx1, cancelCtx1 := context.WithCancel(context.Background())
	ctx2, cancelCtx2 := context.WithCancel(context.Background())

	go fetchMetadataWithChannel(ctx1, lastInstanceEtag, instanceCustomDataDirectory, gceMetadataURL, instanceChannel)
	go fetchMetadataWithChannel(ctx2, lastProjectEtag, projectCustomDataDirectory, gceMetadataURL, projectChannel)

	select {
	case instance := <-instanceChannel:
		if instance.err != nil {
			err = instance.err
			break
		}
		cancelCtx2()
		instanceMetadata = instance.metadata
		instanceEtag = instance.etag
		projectMetadata, projectEtag, err = fetchMetadataTag(ctx1, "", projectCustomDataDirectory, gceMetadataURL)
		if err != nil {
			break
		}
	case project := <-projectChannel:
		if project.err != nil {
			err = project.err
			break
		}
		cancelCtx1()
		projectMetadata = project.metadata
		projectEtag = project.etag
		instanceMetadata, instanceEtag, err = fetchMetadataTag(ctx2, "", instanceCustomDataDirectory, gceMetadataURL)
		if err != nil {
			break
		}
	}

	if err != nil {
		glog.Errorf("Failed to fetch/parse metadata from metadata server: %s", err)
		return nil, "", "", err
	}

	userConfig, err := getUserConfigFromMetadata(instanceMetadata, projectMetadata)
	if err != nil {
		glog.Errorf("Failed to resolve userconfig: %s", err)
		return nil, "", "", err
	}
	return userConfig, instanceEtag, projectEtag, nil
}

// parseRawMetadata converts instance custom metadata from string to key:value pairs.
func parseRawMetadata(rawMetadata string) (map[string]string, error) {
	output := make(map[string]string)

	if err := json.Unmarshal([]byte(rawMetadata), &output); err != nil {
		return nil, err
	}
	return output, nil
}

// GetInstanceID returns the id of the instance.
func GetInstanceID() (uint64, error) {
	var resp, err = metadataServer.InstanceID()
	if err != nil {
		return 0, err
	}

	return strconv.ParseUint(string(resp), 10, 64)
}

// Helper function to get metadata value of a key with 'cos-' prefix and the
// corresponding key with 'gci-' prefix. For example, 'cos-update-strategy' and
// 'gci-update-strategy'. The value of 'gci-' key is returned only if the function
// fail to get the value of 'cos-' key.
func getCOSGCIConfigSetting(cosKey string, gciKey string, instanceMetadata map[string]string, projectMetadata map[string]string) (string, bool) {
	value, ok := instanceMetadata[cosKey]
	if ok {
		return value, ok
	}
	value, ok = instanceMetadata[gciKey]
	if ok {
		return value, ok
	}
	value, ok = projectMetadata[cosKey]
	if ok {
		return value, ok
	}
	value, ok = projectMetadata[gciKey]
	if ok {
		return value, ok
	}
	return "", false
}

// Gets user config based on the metadata keys. An empty InstanceConfig is returned
// if there is no InstanceConfig-related metadata in the pairs.
func getUserConfigFromMetadata(instanceMetadata map[string]string, projectMetadata map[string]string) (*protos.InstanceConfig, error) {
	var configStr string
	var err error
	var ok, boolean bool
	userConfig := new(protos.InstanceConfig)
	userConfig.HealthMonitorConfig = new(protos.HealthMonitorConfig)

	// Get legacy instance config from metadata. This is deprecated, but if this is still
	// being specified, use it and ignore others.
	if configStr, ok = getCOSGCIConfigSetting("", gciLegacyConfigKey, instanceMetadata, projectMetadata); ok {
		if configStr != "" {
			if err := jsonpb.UnmarshalString(configStr, userConfig); err != nil {
				return nil, fmt.Errorf("failed to unmarshal InstanceConfig %s: %s", configStr, err)
			}
		}
		return userConfig, nil
	}

	// Get individual config settings. Keys with 'cos-' prefix have the priority.
	if configStr, ok = getCOSGCIConfigSetting(cosKeyUpdateStrategy, gciKeyUpdateStrategy, instanceMetadata, projectMetadata); ok {
		if configStr == "update_disabled" {
			userConfig.UpdateStrategy = proto.String(configStr)
		} else {
			userConfig.UpdateStrategy = proto.String("")
		}
	}

	if configStr, ok = getCOSGCIConfigSetting(cosKeyMetricsEnabled, gciKeyMetricsEnabled, instanceMetadata, projectMetadata); ok {
		if boolean, err = strconv.ParseBool(configStr); err == nil {
			userConfig.MetricsEnabled = proto.Bool(boolean)
		}
	}

	if configStr, ok := getCOSGCIConfigSetting(keyGoogleLoggingEnabled, "", instanceMetadata, projectMetadata); ok {
		if boolean, err = strconv.ParseBool(configStr); err == nil {
			userConfig.HealthMonitorConfig.LoggingEnabled = proto.Bool(boolean)
		}
	}

	if configStr, ok := getCOSGCIConfigSetting(keyGoogleMonitoringEnabled, "", instanceMetadata, projectMetadata); ok {
		if boolean, err = strconv.ParseBool(configStr); err == nil {
			userConfig.HealthMonitorConfig.MonitoringEnabled = proto.Bool(boolean)
		}
	}

	// Set Enforced to true if user is enabling logging or monitoring.
	if userConfig.HealthMonitorConfig.GetLoggingEnabled() || userConfig.HealthMonitorConfig.GetMonitoringEnabled() {
		userConfig.HealthMonitorConfig.Enforced = proto.Bool(true)
	}

	return userConfig, nil
}
