// 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 logging

import (
	"runtime"
	"strings"
	"sync"

	"cloud.google.com/go/logging/internal"
	mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
)

// CommonResource sets the monitored resource associated with all log entries
// written from a Logger. If not provided, the resource is automatically
// detected based on the running environment (on GCE, GCR, GCF and GAE Standard only).
// This value can be overridden per-entry by setting an Entry's Resource field.
func CommonResource(r *mrpb.MonitoredResource) LoggerOption { return commonResource{r} }

type commonResource struct{ *mrpb.MonitoredResource }

func (r commonResource) set(l *Logger) { l.commonResource = r.MonitoredResource }

type resource struct {
	pb    *mrpb.MonitoredResource
	attrs internal.ResourceAttributesGetter
	once  *sync.Once
}

var detectedResource = &resource{
	attrs: internal.ResourceAttributes(),
	once:  new(sync.Once),
}

func (r *resource) metadataProjectID() string {
	return r.attrs.Metadata("project/project-id")
}

func (r *resource) metadataZone() string {
	zone := r.attrs.Metadata("instance/zone")
	if zone != "" {
		return zone[strings.LastIndex(zone, "/")+1:]
	}
	return ""
}

func (r *resource) metadataRegion() string {
	region := r.attrs.Metadata("instance/region")
	if region != "" {
		return region[strings.LastIndex(region, "/")+1:]
	}
	return ""
}

// isMetadataActive queries valid response on "/computeMetadata/v1/" URL
func (r *resource) isMetadataActive() bool {
	data := r.attrs.Metadata("")
	return data != ""
}

// isAppEngine returns true for both standard and flex
func (r *resource) isAppEngine() bool {
	service := r.attrs.EnvVar("GAE_SERVICE")
	version := r.attrs.EnvVar("GAE_VERSION")
	instance := r.attrs.EnvVar("GAE_INSTANCE")
	return service != "" && version != "" && instance != ""
}

func detectAppEngineResource() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		projectID = detectedResource.attrs.EnvVar("GOOGLE_CLOUD_PROJECT")
	}
	if projectID == "" {
		return nil
	}
	zone := detectedResource.metadataZone()
	service := detectedResource.attrs.EnvVar("GAE_SERVICE")
	version := detectedResource.attrs.EnvVar("GAE_VERSION")

	return &mrpb.MonitoredResource{
		Type: "gae_app",
		Labels: map[string]string{
			"project_id": projectID,
			"module_id":  service,
			"version_id": version,
			"zone":       zone,
		},
	}
}

func (r *resource) isCloudFunction() bool {
	target := r.attrs.EnvVar("FUNCTION_TARGET")
	signature := r.attrs.EnvVar("FUNCTION_SIGNATURE_TYPE")
	// note that this envvar is also present in Cloud Run environments
	service := r.attrs.EnvVar("K_SERVICE")
	return target != "" && signature != "" && service != ""
}

func detectCloudFunction() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		return nil
	}
	region := detectedResource.metadataRegion()
	functionName := detectedResource.attrs.EnvVar("K_SERVICE")
	return &mrpb.MonitoredResource{
		Type: "cloud_function",
		Labels: map[string]string{
			"project_id":    projectID,
			"region":        region,
			"function_name": functionName,
		},
	}
}

func (r *resource) isCloudRunService() bool {
	config := r.attrs.EnvVar("K_CONFIGURATION")
	// note that this envvar is also present in Cloud Function environments
	service := r.attrs.EnvVar("K_SERVICE")
	revision := r.attrs.EnvVar("K_REVISION")
	return config != "" && service != "" && revision != ""
}

func (r *resource) isCloudRunJob() bool {
	if r.attrs.EnvVar("CLOUD_RUN_JOB") == "" {
		return false
	}
	if r.attrs.EnvVar("CLOUD_RUN_EXECUTION") == "" {
		return false
	}
	if r.attrs.EnvVar("CLOUD_RUN_TASK_INDEX") == "" {
		return false
	}
	if r.attrs.EnvVar("CLOUD_RUN_TASK_ATTEMPT") == "" {
		return false
	}
	return true
}

func detectCloudRunServiceResource() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		return nil
	}
	region := detectedResource.metadataRegion()
	config := detectedResource.attrs.EnvVar("K_CONFIGURATION")
	service := detectedResource.attrs.EnvVar("K_SERVICE")
	revision := detectedResource.attrs.EnvVar("K_REVISION")
	return &mrpb.MonitoredResource{
		Type: "cloud_run_revision",
		Labels: map[string]string{
			"project_id":         projectID,
			"location":           region,
			"service_name":       service,
			"revision_name":      revision,
			"configuration_name": config,
		},
	}
}

func detectCloudRunJobResource() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		return nil
	}
	region := detectedResource.metadataRegion()
	job := detectedResource.attrs.EnvVar("CLOUD_RUN_JOB")
	return &mrpb.MonitoredResource{
		Type: "cloud_run_job",
		Labels: map[string]string{
			"project_id": projectID,
			"location":   region,
			"job_name":   job,
		},
	}
}

func (r *resource) isKubernetesEngine() bool {
	clusterName := r.attrs.Metadata("instance/attributes/cluster-name")
	if clusterName == "" {
		return false
	}
	return true
}

func detectKubernetesResource() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		return nil
	}
	clusterName := detectedResource.attrs.Metadata("instance/attributes/cluster-name")
	clusterLocation := detectedResource.attrs.Metadata("instance/attributes/cluster-location")
	namespaceName := detectedResource.attrs.ReadAll("/var/run/secrets/kubernetes.io/serviceaccount/namespace")
	if namespaceName == "" {
		// if automountServiceAccountToken is disabled allow to customize
		// the namespace via environment
		namespaceName = detectedResource.attrs.EnvVar("NAMESPACE_NAME")
	}
	// note: if deployment customizes hostname, HOSTNAME envvar will have invalid content
	podName := detectedResource.attrs.EnvVar("HOSTNAME")
	// there is no way to derive container name from within container; use custom envvar if available
	containerName := detectedResource.attrs.EnvVar("CONTAINER_NAME")
	return &mrpb.MonitoredResource{
		Type: "k8s_container",
		Labels: map[string]string{
			"cluster_name":   clusterName,
			"location":       clusterLocation,
			"project_id":     projectID,
			"pod_name":       podName,
			"namespace_name": namespaceName,
			"container_name": containerName,
		},
	}
}

func (r *resource) isComputeEngine() bool {
	preempted := r.attrs.Metadata("instance/preempted")
	platform := r.attrs.Metadata("instance/cpu-platform")
	appBucket := r.attrs.Metadata("instance/attributes/gae_app_bucket")
	return preempted != "" && platform != "" && appBucket == ""
}

func detectComputeEngineResource() *mrpb.MonitoredResource {
	projectID := detectedResource.metadataProjectID()
	if projectID == "" {
		return nil
	}
	id := detectedResource.attrs.Metadata("instance/id")
	zone := detectedResource.metadataZone()
	return &mrpb.MonitoredResource{
		Type: "gce_instance",
		Labels: map[string]string{
			"project_id":  projectID,
			"instance_id": id,
			"zone":        zone,
		},
	}
}

func detectResource() *mrpb.MonitoredResource {
	detectedResource.once.Do(func() {
		if detectedResource.isMetadataActive() {
			name := systemProductName()
			switch {
			case name == "Google App Engine", detectedResource.isAppEngine():
				detectedResource.pb = detectAppEngineResource()
			case name == "Google Cloud Functions", detectedResource.isCloudFunction():
				detectedResource.pb = detectCloudFunction()
			// cannot use name validation for Cloud Run resources because
			// both of them set product name to "Google Cloud Run"
			case detectedResource.isCloudRunService():
				detectedResource.pb = detectCloudRunServiceResource()
			case detectedResource.isCloudRunJob():
				detectedResource.pb = detectCloudRunJobResource()
			// cannot use name validation for GKE and GCE because
			// both of them set product name to "Google Compute Engine"
			case detectedResource.isKubernetesEngine():
				detectedResource.pb = detectKubernetesResource()
			case detectedResource.isComputeEngine():
				detectedResource.pb = detectComputeEngineResource()
			}
		}
	})
	return detectedResource.pb
}

// systemProductName reads resource type on the Linux-based environments such as
// Cloud Functions, Cloud Run, GKE, GCE, GAE, etc.
func systemProductName() string {
	if runtime.GOOS != "linux" {
		// We don't have any non-Linux clues available, at least yet.
		return ""
	}
	slurp := detectedResource.attrs.ReadAll("/sys/class/dmi/id/product_name")
	return strings.TrimSpace(slurp)
}

var resourceInfo = map[string]struct{ rtype, label string }{
	"organizations":   {"organization", "organization_id"},
	"folders":         {"folder", "folder_id"},
	"projects":        {"project", "project_id"},
	"billingAccounts": {"billing_account", "account_id"},
}

func monitoredResource(parent string) *mrpb.MonitoredResource {
	parts := strings.SplitN(parent, "/", 2)
	if len(parts) != 2 {
		return globalResource(parent)
	}
	info, ok := resourceInfo[parts[0]]
	if !ok {
		return globalResource(parts[1])
	}
	return &mrpb.MonitoredResource{
		Type:   info.rtype,
		Labels: map[string]string{info.label: parts[1]},
	}
}

func globalResource(projectID string) *mrpb.MonitoredResource {
	return &mrpb.MonitoredResource{
		Type: "global",
		Labels: map[string]string{
			"project_id": projectID,
		},
	}
}
