// Copyright 2016 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 controller is a library for interacting with the Google Cloud Debugger's Debuglet Controller service.
package controller

import (
	"crypto/sha256"
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"sync"

	"golang.org/x/net/context"
	"golang.org/x/oauth2"
	cd "google.golang.org/api/clouddebugger/v2"
	"google.golang.org/api/googleapi"
	"google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

const (
	// agentVersionString identifies the agent to the service.
	agentVersionString = "google.com/go-gcp/v0.2"
	// initWaitToken is the wait token sent in the first Update request to a server.
	initWaitToken = "init"
)

var (
	// ErrListUnchanged is returned by List if the server time limit is reached
	// before the list of breakpoints changes.
	ErrListUnchanged = errors.New("breakpoint list unchanged")
	// ErrDebuggeeDisabled is returned by List or Update if the server has disabled
	// this Debuggee.  The caller can retry later.
	ErrDebuggeeDisabled = errors.New("debuglet disabled by server")
)

// Controller manages a connection to the Debuglet Controller service.
type Controller struct {
	s serviceInterface
	// waitToken is sent with List requests so the server knows which set of
	// breakpoints this client has already seen. Each successful List request
	// returns a new waitToken to send in the next request.
	waitToken string
	// verbose determines whether to do some logging
	verbose bool
	// options, uniquifier and description are used in register.
	options     Options
	uniquifier  string
	description string
	// labels are included when registering the debuggee. They should contain
	// the module name, version and minorversion, and are used by the debug UI
	// to label the correct version active for debugging.
	labels map[string]string
	// mu protects debuggeeID
	mu sync.Mutex
	// debuggeeID is returned from the server on registration, and is passed back
	// to the server in List and Update requests.
	debuggeeID string
}

// Options controls how the Debuglet Controller client identifies itself to the server.
// See https://cloud.google.com/storage/docs/projects and
// https://cloud.google.com/tools/cloud-debugger/setting-up-on-compute-engine
// for further documentation of these parameters.
type Options struct {
	ProjectNumber  string              // GCP Project Number.
	ProjectID      string              // GCP Project ID.
	AppModule      string              // Module name for the debugged program.
	AppVersion     string              // Version number for this module.
	SourceContexts []*cd.SourceContext // Description of source.
	Verbose        bool
	TokenSource    oauth2.TokenSource // Source of Credentials used for Stackdriver Debugger.
}

type serviceInterface interface {
	Register(ctx context.Context, req *cd.RegisterDebuggeeRequest) (*cd.RegisterDebuggeeResponse, error)
	Update(ctx context.Context, debuggeeID, breakpointID string, req *cd.UpdateActiveBreakpointRequest) (*cd.UpdateActiveBreakpointResponse, error)
	List(ctx context.Context, debuggeeID, waitToken string) (*cd.ListActiveBreakpointsResponse, error)
}

var newService = func(ctx context.Context, tokenSource oauth2.TokenSource) (serviceInterface, error) {
	httpClient, endpoint, err := htransport.NewClient(ctx, option.WithTokenSource(tokenSource))
	if err != nil {
		return nil, err
	}
	s, err := cd.New(httpClient)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return &service{s: s}, nil
}

type service struct {
	s *cd.Service
}

func (s service) Register(ctx context.Context, req *cd.RegisterDebuggeeRequest) (*cd.RegisterDebuggeeResponse, error) {
	call := cd.NewControllerDebuggeesService(s.s).Register(req)
	return call.Context(ctx).Do()
}

func (s service) Update(ctx context.Context, debuggeeID, breakpointID string, req *cd.UpdateActiveBreakpointRequest) (*cd.UpdateActiveBreakpointResponse, error) {
	call := cd.NewControllerDebuggeesBreakpointsService(s.s).Update(debuggeeID, breakpointID, req)
	return call.Context(ctx).Do()
}

func (s service) List(ctx context.Context, debuggeeID, waitToken string) (*cd.ListActiveBreakpointsResponse, error) {
	call := cd.NewControllerDebuggeesBreakpointsService(s.s).List(debuggeeID)
	call.WaitToken(waitToken)
	return call.Context(ctx).Do()
}

// NewController connects to the Debuglet Controller server using the given options,
// and returns a Controller for that connection.
// Google Application Default Credentials are used to connect to the Debuglet Controller;
// see https://developers.google.com/identity/protocols/application-default-credentials
func NewController(ctx context.Context, o Options) (*Controller, error) {
	// We build a JSON encoding of o.SourceContexts so we can hash it.
	scJSON, err := json.Marshal(o.SourceContexts)
	if err != nil {
		scJSON = nil
		o.SourceContexts = nil
	}
	const minorversion = "107157" // any arbitrary numeric string

	// Compute a uniquifier string by hashing the project number, app module name,
	// app module version, debuglet version, and source context.
	// The choice of hash function is arbitrary.
	h := sha256.Sum256([]byte(fmt.Sprintf("%d %s %d %s %d %s %d %s %d %s %d %s",
		len(o.ProjectNumber), o.ProjectNumber,
		len(o.AppModule), o.AppModule,
		len(o.AppVersion), o.AppVersion,
		len(agentVersionString), agentVersionString,
		len(scJSON), scJSON,
		len(minorversion), minorversion)))
	uniquifier := fmt.Sprintf("%X", h[0:16]) // 32 hex characters

	description := o.ProjectID
	if o.AppModule != "" {
		description += "-" + o.AppModule
	}
	if o.AppVersion != "" {
		description += "-" + o.AppVersion
	}

	s, err := newService(ctx, o.TokenSource)
	if err != nil {
		return nil, err
	}

	// Construct client.
	c := &Controller{
		s:           s,
		waitToken:   initWaitToken,
		verbose:     o.Verbose,
		options:     o,
		uniquifier:  uniquifier,
		description: description,
		labels: map[string]string{
			"module":       o.AppModule,
			"version":      o.AppVersion,
			"minorversion": minorversion,
		},
	}

	return c, nil
}

func (c *Controller) getDebuggeeID(ctx context.Context) (string, error) {
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.debuggeeID != "" {
		return c.debuggeeID, nil
	}
	// The debuglet hasn't been registered yet, or it is disabled and we should try registering again.
	if err := c.register(ctx); err != nil {
		return "", err
	}
	return c.debuggeeID, nil
}

// List retrieves the current list of breakpoints from the server.
// If the set of breakpoints on the server is the same as the one returned in
// the previous call to List, the server can delay responding until it changes,
// and return an error instead if no change occurs before a time limit the
// server sets.  List can't be called concurrently with itself.
func (c *Controller) List(ctx context.Context) (*cd.ListActiveBreakpointsResponse, error) {
	id, err := c.getDebuggeeID(ctx)
	if err != nil {
		return nil, err
	}
	resp, err := c.s.List(ctx, id, c.waitToken)
	if err != nil {
		if isAbortedError(err) {
			return nil, ErrListUnchanged
		}
		// For other errors, the protocol requires that we attempt to re-register.
		c.mu.Lock()
		defer c.mu.Unlock()
		if regError := c.register(ctx); regError != nil {
			return nil, regError
		}
		return nil, err
	}
	if resp == nil {
		return nil, errors.New("no response")
	}
	if c.verbose {
		log.Printf("List response: %v", resp)
	}
	c.waitToken = resp.NextWaitToken
	return resp, nil
}

// isAbortedError tests if err is a *googleapi.Error, that it contains one error
// in Errors, and that that error's Reason is "aborted".
func isAbortedError(err error) bool {
	e, _ := err.(*googleapi.Error)
	if e == nil {
		return false
	}
	if len(e.Errors) != 1 {
		return false
	}
	return e.Errors[0].Reason == "aborted"
}

// Update reports information to the server about a breakpoint that was hit.
// Update can be called concurrently with List and Update.
func (c *Controller) Update(ctx context.Context, breakpointID string, bp *cd.Breakpoint) error {
	req := &cd.UpdateActiveBreakpointRequest{Breakpoint: bp}
	if c.verbose {
		log.Printf("sending update for %s: %v", breakpointID, req)
	}
	id, err := c.getDebuggeeID(ctx)
	if err != nil {
		return err
	}
	_, err = c.s.Update(ctx, id, breakpointID, req)
	return err
}

// register calls the Debuglet Controller Register method, and sets c.debuggeeID.
// c.mu should be locked while calling this function.  List and Update can't
// make progress until it returns.
func (c *Controller) register(ctx context.Context) error {
	req := cd.RegisterDebuggeeRequest{
		Debuggee: &cd.Debuggee{
			AgentVersion:   agentVersionString,
			Description:    c.description,
			Project:        c.options.ProjectNumber,
			SourceContexts: c.options.SourceContexts,
			Uniquifier:     c.uniquifier,
			Labels:         c.labels,
		},
	}
	resp, err := c.s.Register(ctx, &req)
	if err != nil {
		return err
	}
	if resp == nil {
		return errors.New("register: no response")
	}
	if resp.Debuggee.IsDisabled {
		// Setting c.debuggeeID to empty makes sure future List and Update calls
		// will call register first.
		c.debuggeeID = ""
	} else {
		c.debuggeeID = resp.Debuggee.Id
	}
	if c.debuggeeID == "" {
		return ErrDebuggeeDisabled
	}
	return nil
}
