// 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

import (
	"http"
	"log"
	"net"
	"once"
	"os"
	"strings"
	"testing"
)

var serverAddr string
var httpServerAddr string

const second = 1e9


type Args struct {
	A, B int
}

type Reply struct {
	C int
}

type Arith int

func (t *Arith) Add(args *Args, reply *Reply) os.Error {
	reply.C = args.A + args.B
	return nil
}

func (t *Arith) Mul(args *Args, reply *Reply) os.Error {
	reply.C = args.A * args.B
	return nil
}

func (t *Arith) Div(args *Args, reply *Reply) os.Error {
	if args.B == 0 {
		return os.ErrorString("divide by zero")
	}
	reply.C = args.A / args.B
	return nil
}

func (t *Arith) Error(args *Args, reply *Reply) os.Error {
	panicln("ERROR")
}

func startServer() {
	Register(new(Arith))

	l, e := net.Listen("tcp", ":0") // any available address
	if e != nil {
		log.Exitf("net.Listen tcp :0: %v", e)
	}
	serverAddr = l.Addr().String()
	log.Stderr("Test RPC server listening on ", serverAddr)
	go Accept(l)

	HandleHTTP()
	l, e = net.Listen("tcp", ":0") // any available address
	if e != nil {
		log.Stderrf("net.Listen tcp :0: %v", e)
		os.Exit(1)
	}
	httpServerAddr = l.Addr().String()
	log.Stderr("Test HTTP RPC server listening on ", httpServerAddr)
	go http.Serve(l, nil)
}

func TestRPC(t *testing.T) {
	once.Do(startServer)

	client, err := Dial("tcp", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	// Synchronous calls
	args := &Args{7, 8}
	reply := new(Reply)
	err = client.Call("Arith.Add", args, reply)
	if err != nil {
		t.Errorf("Add: expected no error but got string %q", err.String())
	}
	if reply.C != args.A+args.B {
		t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
	}

	args = &Args{7, 8}
	reply = new(Reply)
	err = client.Call("Arith.Mul", args, reply)
	if err != nil {
		t.Errorf("Mul: expected no error but got string %q", err.String())
	}
	if reply.C != args.A*args.B {
		t.Errorf("Mul: expected %d got %d", reply.C, args.A*args.B)
	}

	// Out of order.
	args = &Args{7, 8}
	mulReply := new(Reply)
	mulCall := client.Go("Arith.Mul", args, mulReply, nil)
	addReply := new(Reply)
	addCall := client.Go("Arith.Add", args, addReply, nil)

	addCall = <-addCall.Done
	if addCall.Error != nil {
		t.Errorf("Add: expected no error but got string %q", addCall.Error.String())
	}
	if addReply.C != args.A+args.B {
		t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
	}

	mulCall = <-mulCall.Done
	if mulCall.Error != nil {
		t.Errorf("Mul: expected no error but got string %q", mulCall.Error.String())
	}
	if mulReply.C != args.A*args.B {
		t.Errorf("Mul: expected %d got %d", mulReply.C, args.A*args.B)
	}

	// Error test
	args = &Args{7, 0}
	reply = new(Reply)
	err = client.Call("Arith.Div", args, reply)
	// expect an error: zero divide
	if err == nil {
		t.Error("Div: expected error")
	} else if err.String() != "divide by zero" {
		t.Error("Div: expected divide by zero error; got", err)
	}
}

func TestHTTPRPC(t *testing.T) {
	once.Do(startServer)

	client, err := DialHTTP("tcp", httpServerAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	// Synchronous calls
	args := &Args{7, 8}
	reply := new(Reply)
	err = client.Call("Arith.Add", args, reply)
	if err != nil {
		t.Errorf("Add: expected no error but got string %q", err.String())
	}
	if reply.C != args.A+args.B {
		t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
	}
}

func TestCheckUnknownService(t *testing.T) {
	once.Do(startServer)

	conn, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing:", err)
	}

	client := NewClient(conn)

	args := &Args{7, 8}
	reply := new(Reply)
	err = client.Call("Unknown.Add", args, reply)
	if err == nil {
		t.Error("expected error calling unknown service")
	} else if strings.Index(err.String(), "service") < 0 {
		t.Error("expected error about service; got", err)
	}
}

func TestCheckUnknownMethod(t *testing.T) {
	once.Do(startServer)

	conn, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing:", err)
	}

	client := NewClient(conn)

	args := &Args{7, 8}
	reply := new(Reply)
	err = client.Call("Arith.Unknown", args, reply)
	if err == nil {
		t.Error("expected error calling unknown service")
	} else if strings.Index(err.String(), "method") < 0 {
		t.Error("expected error about method; got", err)
	}
}

func TestCheckBadType(t *testing.T) {
	once.Do(startServer)

	conn, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing:", err)
	}

	client := NewClient(conn)

	reply := new(Reply)
	err = client.Call("Arith.Add", reply, reply) // args, reply would be the correct thing to use
	if err == nil {
		t.Error("expected error calling Arith.Add with wrong arg type")
	} else if strings.Index(err.String(), "type") < 0 {
		t.Error("expected error about type; got", err)
	}
}

type Bad int
type local struct{}

func (t *Bad) ArgNotPointer(args Args, reply *Reply) os.Error {
	return nil
}

func (t *Bad) ArgNotPointerToStruct(args *int, reply *Reply) os.Error {
	return nil
}

func (t *Bad) ReplyNotPointer(args *Args, reply Reply) os.Error {
	return nil
}

func (t *Bad) ReplyNotPointerToStruct(args *Args, reply *int) os.Error {
	return nil
}

func (t *Bad) ArgNotPublic(args *local, reply *Reply) os.Error {
	return nil
}

func (t *Bad) ReplyNotPublic(args *Args, reply *local) os.Error {
	return nil
}

// Check that registration handles lots of bad methods and a type with no suitable methods.
func TestRegistrationError(t *testing.T) {
	err := Register(new(Bad))
	if err == nil {
		t.Errorf("expected error registering bad type")
	}
}
