// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package metrics provides a service for reporting metrics to
// Stackdriver, or locally during development.
package metrics

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

	"cloud.google.com/go/compute/metadata"
	"contrib.go.opencensus.io/exporter/prometheus"
	"contrib.go.opencensus.io/exporter/stackdriver"
	"go.opencensus.io/stats/view"
	"google.golang.org/appengine"
	mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
)

// NewService initializes a *Service.
//
// The Service returned is configured to send metric data to
// StackDriver. When not running on GCE, it will host metrics through
// a prometheus HTTP handler.
//
// views will be passed to view.Register for export to the metric
// service.
func NewService(resource *MonitoredResource, views []*view.View) (*Service, error) {
	err := view.Register(views...)
	if err != nil {
		return nil, err
	}

	if !metadata.OnGCE() {
		view.SetReportingPeriod(5 * time.Second)
		pe, err := prometheus.NewExporter(prometheus.Options{})
		if err != nil {
			return nil, fmt.Errorf("prometheus.NewExporter: %w", err)
		}
		view.RegisterExporter(pe)
		return &Service{pExporter: pe}, nil
	}

	projID, err := metadata.ProjectID()
	if err != nil {
		return nil, err
	}
	if resource == nil {
		return nil, errors.New("resource is required, got nil")
	}
	sde, err := stackdriver.NewExporter(stackdriver.Options{
		ProjectID:         projID,
		MonitoredResource: resource,
		ReportingInterval: time.Minute, // Minimum interval for Stackdriver is 1 minute.
	})
	if err != nil {
		return nil, err
	}

	// Minimum interval for Stackdriver is 1 minute.
	view.SetReportingPeriod(time.Minute)
	// Start the metrics exporter.
	if err := sde.StartMetricsExporter(); err != nil {
		return nil, err
	}

	return &Service{sdExporter: sde}, nil
}

// Service controls metric exporters.
type Service struct {
	sdExporter *stackdriver.Exporter
	pExporter  *prometheus.Exporter
}

func (m *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if m.pExporter != nil {
		m.pExporter.ServeHTTP(w, r)
		return
	}
	http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}

// Stop flushes metrics and stops exporting. Stop should be called
// before exiting.
func (m *Service) Stop() {
	if sde := m.sdExporter; sde != nil {
		// Flush any unsent data before exiting.
		sde.Flush()

		sde.StopMetricsExporter()
	}
}

// MonitoredResource wraps a *mrpb.MonitoredResource to implement the
// monitoredresource.MonitoredResource interface.
type MonitoredResource mrpb.MonitoredResource

func (r *MonitoredResource) MonitoredResource() (resType string, labels map[string]string) {
	return r.Type, r.Labels
}

// GCEResource populates a MonitoredResource with GCE Metadata.
//
// The returned MonitoredResource will have the type set to "generic_task".
func GCEResource(jobName string) (*MonitoredResource, error) {
	projID, err := metadata.ProjectID()
	if err != nil {
		return nil, err
	}
	zone, err := metadata.Zone()
	if err != nil {
		return nil, err
	}
	inst, err := metadata.InstanceName()
	if err != nil {
		return nil, err
	}
	group, err := instanceGroupName()
	if err != nil {
		return nil, err
	} else if group == "" {
		group = projID
	}

	return (*MonitoredResource)(&mrpb.MonitoredResource{
		Type: "generic_task", // See: https://cloud.google.com/monitoring/api/resources#tag_generic_task
		Labels: map[string]string{
			"project_id": projID,
			"location":   zone,
			"namespace":  group,
			"job":        jobName,
			"task_id":    inst,
		},
	}), nil
}

// GAEResource returns a *MonitoredResource with fields populated and
// for StackDriver.
//
// The resource will be in StackDrvier's gae_instance type.
func GAEResource(ctx context.Context) (*MonitoredResource, error) {
	if !appengine.IsAppEngine() {
		return nil, fmt.Errorf("not running on appengine")
	}
	projID, err := metadata.ProjectID()
	if err != nil {
		return nil, err
	}
	return (*MonitoredResource)(&mrpb.MonitoredResource{
		Type: "gae_instance",
		Labels: map[string]string{
			"project_id":  projID,
			"module_id":   appengine.ModuleName(ctx),
			"version_id":  appengine.VersionID(ctx),
			"instance_id": appengine.InstanceID(),
			"location":    appengine.Datacenter(ctx),
		},
	}), nil
}

// instanceGroupName fetches the instanceGroupName from the instance
// metadata.
//
// The instance group manager applies a custom "created-by" attribute
// to the instance, which is not part of the metadata package API, and
// must be queried separately.
//
// An empty string will be returned if a metadata.NotDefinedError is
// returned when fetching metadata. An error will be returned if other
// errors occur when fetching metadata.
func instanceGroupName() (string, error) {
	ig, err := metadata.InstanceAttributeValue("created-by")
	if errors.As(err, new(metadata.NotDefinedError)) {
		return "", nil
	} else if err != nil {
		return "", err
	}
	// "created-by" format: "projects/{{InstanceID}}/zones/{{Zone}}/instanceGroupManagers/{{Instance Group Name}}
	ig = path.Base(ig)
	return ig, nil
}
