// Copyright 2009 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 rpc

/*
	Some HTML presented at http://machine:port/debug/rpc
	Lists services, their methods, and some statistics, still rudimentary.
*/

import (
	"fmt"
	"http"
	"sort"
	"template"
)

const debugText = `<html>
	<body>
	<title>Services</title>
	{.repeated section @}
	<hr>
	Service {name}
	<hr>
		<table>
		<th align=center>Method</th><th align=center>Calls</th>
		{.repeated section meth}
			<tr>
			<td align=left font=fixed>{name}({m.argType}, {m.replyType}) os.Error</td>
			<td align=center>{m.numCalls}</td>
			</tr>
		{.end}
		</table>
	{.end}
	</body>
	</html>`

var debug = template.MustParse(debugText, nil)

type debugMethod struct {
	m    *methodType
	name string
}

type methodArray []debugMethod

type debugService struct {
	s    *service
	name string
	meth methodArray
}

type serviceArray []debugService

func (s serviceArray) Len() int           { return len(s) }
func (s serviceArray) Less(i, j int) bool { return s[i].name < s[j].name }
func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

func (m methodArray) Len() int           { return len(m) }
func (m methodArray) Less(i, j int) bool { return m[i].name < m[j].name }
func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }

// Runs at /debug/rpc
func debugHTTP(c *http.Conn, req *http.Request) {
	// Build a sorted version of the data.
	var services = make(serviceArray, len(server.serviceMap))
	i := 0
	server.Lock()
	for sname, service := range server.serviceMap {
		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
		j := 0
		for mname, method := range service.method {
			services[i].meth[j] = debugMethod{method, mname}
			j++
		}
		sort.Sort(services[i].meth)
		i++
	}
	server.Unlock()
	sort.Sort(services)
	err := debug.Execute(services, c)
	if err != nil {
		fmt.Fprintln(c, "rpc: error executing template:", err.String())
	}
}
