// Copyright 2018 The Goma 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 server

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

	"contrib.go.opencensus.io/exporter/stackdriver"
	"contrib.go.opencensus.io/exporter/stackdriver/monitoredresource"
	"contrib.go.opencensus.io/exporter/stackdriver/propagation"
	"go.opencensus.io/plugin/ocgrpc"
	"go.opencensus.io/plugin/ochttp"
	"go.opencensus.io/stats/view"
	"go.opencensus.io/trace"
	"google.golang.org/api/option"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	"go.chromium.org/goma/server/log"
	"go.chromium.org/goma/server/log/errorreporter"
)

var (
	exporter *stackdriver.Exporter

	// Increased from Default 10 seconds for quota limit.
	// The recommended reporting period by Stackdriver Monitoring is >= 1 minute:
	// https://cloud.google.com/monitoring/custom-metrics/creating-metrics#writing-ts
	// https://pkg.go.dev/go.opencensus.io/stats/view?tab=doc#SetReportingPeriod
	reportingInterval = 90 * time.Second
)

// Init initializes opencensus instrumentations, and error reporter.
// If projectID is not empty, it registers stackdriver exporter for the project.
// It also calls SetupHTTPClient.
func Init(ctx context.Context, projectID, name string) error {
	logger := log.FromContext(ctx)
	if projectID != "" {
		logger.Infof("send stackdriver trace log to project %s", projectID)

		var err error
		exporter, err = stackdriver.NewExporter(stackdriver.Options{
			ProjectID: projectID,
			OnError: func(err error) {
				switch status.Code(err) {
				case codes.Unavailable:
					logger.Warnf("Failed to export to Stackdriver: %v", err)
				default:
					logger.Errorf("Failed to export to Stackdriver: %v", err)
				}
			},
			MonitoredResource: monitoredresource.Autodetect(),

			// Disallow grpc in google-api-go-client to send stats/trace of monitoring grpc's api call.
			MonitoringClientOptions: []option.ClientOption{option.WithGRPCDialOption(grpc.WithStatsHandler(nil))},
			TraceClientOptions:      []option.ClientOption{option.WithGRPCDialOption(grpc.WithStatsHandler(nil))},
		})
		if err != nil {
			return fmt.Errorf("failed to create exporter: %v", err)
		}
		view.RegisterExporter(exporter)
		trace.RegisterExporter(exporter)
		view.SetReportingPeriod(reportingInterval)

		errorreporter.DefaultErrorReporter = errorreporter.New(ctx, projectID, serverName(ctx, name))
	}

	err := view.Register(ocgrpc.DefaultServerViews...)
	if err != nil {
		return fmt.Errorf("failed to subscribe ocgrpc view: %v", err)
	}
	err = view.Register(ocgrpc.DefaultClientViews...)
	if err != nil {
		return fmt.Errorf("failed to subscribe ocgrpc client view: %v", err)
	}
	err = view.Register(ochttp.DefaultServerViews...)
	if err != nil {
		return fmt.Errorf("failed to subscribe ochttp view: %v", err)
	}
	err = view.Register(ochttp.DefaultClientViews...)
	if err != nil {
		return fmt.Errorf("failed to subscribe ochttp view: %v", err)
	}
	SetupHTTPClient()

	err = view.Register(procStatViews...)
	if err != nil {
		return fmt.Errorf("failed to subscribe proc stat view: %v", err)
	}
	go reportProcStats(context.Background())
	return nil
}

// SetupHTTPClient sets up http default client to monitor by opencensus.
func SetupHTTPClient() {
	// we can't set the transport as http.DefaultTransport, because
	// ochttp.Transport will use http.DefaultTransport so it causes
	// recursive calls.
	http.DefaultClient = &http.Client{
		Transport: &ochttp.Transport{
			Propagation: &propagation.HTTPFormat{},
		},
	}
}

// Flush flushes opencensus data.
func Flush() {
	if exporter == nil {
		return
	}
	exporter.Flush()
}
