// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
Package runtime exposes information about the resource usage of the application.
It also provides a way to run code in a new background context of a module.

This package does not work on Managed VMs.
*/
package runtime // import "google.golang.org/appengine/runtime"

import (
	"net/http"

	"golang.org/x/net/context"

	"google.golang.org/appengine"
	"google.golang.org/appengine/internal"
	pb "google.golang.org/appengine/internal/system"
)

// Statistics represents the system's statistics.
type Statistics struct {
	// CPU records the CPU consumed by this instance, in megacycles.
	CPU struct {
		Total   float64
		Rate1M  float64 // consumption rate over one minute
		Rate10M float64 // consumption rate over ten minutes
	}
	// RAM records the memory used by the instance, in megabytes.
	RAM struct {
		Current    float64
		Average1M  float64 // average usage over one minute
		Average10M float64 // average usage over ten minutes
	}
}

func Stats(c context.Context) (*Statistics, error) {
	req := &pb.GetSystemStatsRequest{}
	res := &pb.GetSystemStatsResponse{}
	if err := internal.Call(c, "system", "GetSystemStats", req, res); err != nil {
		return nil, err
	}
	s := &Statistics{}
	if res.Cpu != nil {
		s.CPU.Total = res.Cpu.GetTotal()
		s.CPU.Rate1M = res.Cpu.GetRate1M()
		s.CPU.Rate10M = res.Cpu.GetRate10M()
	}
	if res.Memory != nil {
		s.RAM.Current = res.Memory.GetCurrent()
		s.RAM.Average1M = res.Memory.GetAverage1M()
		s.RAM.Average10M = res.Memory.GetAverage10M()
	}
	return s, nil
}

/*
RunInBackground makes an API call that triggers an /_ah/background request.

There are two independent code paths that need to make contact:
the RunInBackground code, and the /_ah/background handler. The matchmaker
loop arranges for the two paths to meet. The RunInBackground code passes
a send to the matchmaker, the /_ah/background passes a recv to the matchmaker,
and the matchmaker hooks them up.
*/

func init() {
	http.HandleFunc("/_ah/background", handleBackground)

	sc := make(chan send)
	rc := make(chan recv)
	sendc, recvc = sc, rc
	go matchmaker(sc, rc)
}

var (
	sendc chan<- send // RunInBackground sends to this
	recvc chan<- recv // handleBackground sends to this
)

type send struct {
	id string
	f  func(context.Context)
}

type recv struct {
	id string
	ch chan<- func(context.Context)
}

func matchmaker(sendc <-chan send, recvc <-chan recv) {
	// When one side of the match arrives before the other
	// it is inserted in the corresponding map.
	waitSend := make(map[string]send)
	waitRecv := make(map[string]recv)

	for {
		select {
		case s := <-sendc:
			if r, ok := waitRecv[s.id]; ok {
				// meet!
				delete(waitRecv, s.id)
				r.ch <- s.f
			} else {
				// waiting for r
				waitSend[s.id] = s
			}
		case r := <-recvc:
			if s, ok := waitSend[r.id]; ok {
				// meet!
				delete(waitSend, r.id)
				r.ch <- s.f
			} else {
				// waiting for s
				waitRecv[r.id] = r
			}
		}
	}
}

var newContext = appengine.NewContext // for testing

func handleBackground(w http.ResponseWriter, req *http.Request) {
	id := req.Header.Get("X-AppEngine-BackgroundRequest")

	ch := make(chan func(context.Context))
	recvc <- recv{id, ch}
	(<-ch)(newContext(req))
}

// RunInBackground runs f in a background goroutine in this process.
// f is provided a context that may outlast the context provided to RunInBackground.
// This is only valid to invoke from a manually scaled module.
func RunInBackground(c context.Context, f func(c context.Context)) error {
	req := &pb.StartBackgroundRequestRequest{}
	res := &pb.StartBackgroundRequestResponse{}
	if err := internal.Call(c, "system", "StartBackgroundRequest", req, res); err != nil {
		return err
	}
	sendc <- send{res.GetRequestId(), f}
	return nil
}

func init() {
	internal.RegisterErrorCodeMap("system", pb.SystemServiceError_ErrorCode_name)
}
