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

// Sockets

package net

import (
	"os"
	"reflect"
	"syscall"
)

// Boolean to int.
func boolint(b bool) int {
	if b {
		return 1
	}
	return 0
}

// Generic socket creation.
func socket(net string, f, p, t int, la, ra syscall.Sockaddr, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err os.Error) {
	// See ../syscall/exec.go for description of ForkLock.
	syscall.ForkLock.RLock()
	s, e := syscall.Socket(f, p, t)
	if e != 0 {
		syscall.ForkLock.RUnlock()
		return nil, os.Errno(e)
	}
	syscall.CloseOnExec(s)
	syscall.ForkLock.RUnlock()

	// Allow reuse of recently-used addresses.
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)

	// Allow broadcast.
	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)

	if la != nil {
		e = syscall.Bind(s, la)
		if e != 0 {
			syscall.Close(s)
			return nil, os.Errno(e)
		}
	}

	if ra != nil {
		e = syscall.Connect(s, ra)
		if e != 0 {
			syscall.Close(s)
			return nil, os.Errno(e)
		}
	}

	sa, _ := syscall.Getsockname(s)
	laddr := toAddr(sa)
	sa, _ = syscall.Getpeername(s)
	raddr := toAddr(sa)

	fd, err = newFD(s, f, p, net, laddr, raddr)
	if err != nil {
		syscall.Close(s)
		return nil, err
	}

	return fd, nil
}

func setsockoptInt(fd, level, opt int, value int) os.Error {
	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd, level, opt, value))
}

func setsockoptNsec(fd, level, opt int, nsec int64) os.Error {
	var tv = syscall.NsecToTimeval(nsec)
	return os.NewSyscallError("setsockopt", syscall.SetsockoptTimeval(fd, level, opt, &tv))
}

func setReadBuffer(fd *netFD, bytes int) os.Error {
	fd.incref()
	defer fd.decref()
	return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes)
}

func setWriteBuffer(fd *netFD, bytes int) os.Error {
	fd.incref()
	defer fd.decref()
	return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes)
}

func setReadTimeout(fd *netFD, nsec int64) os.Error {
	fd.rdeadline_delta = nsec
	return nil
}

func setWriteTimeout(fd *netFD, nsec int64) os.Error {
	fd.wdeadline_delta = nsec
	return nil
}

func setTimeout(fd *netFD, nsec int64) os.Error {
	if e := setReadTimeout(fd, nsec); e != nil {
		return e
	}
	return setWriteTimeout(fd, nsec)
}

func setReuseAddr(fd *netFD, reuse bool) os.Error {
	fd.incref()
	defer fd.decref()
	return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse))
}

func bindToDevice(fd *netFD, dev string) os.Error {
	// TODO(rsc): call setsockopt with null-terminated string pointer
	return os.EINVAL
}

func setDontRoute(fd *netFD, dontroute bool) os.Error {
	fd.incref()
	defer fd.decref()
	return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute))
}

func setKeepAlive(fd *netFD, keepalive bool) os.Error {
	fd.incref()
	defer fd.decref()
	return setsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive))
}

func setLinger(fd *netFD, sec int) os.Error {
	var l syscall.Linger
	if sec >= 0 {
		l.Onoff = 1
		l.Linger = int32(sec)
	} else {
		l.Onoff = 0
		l.Linger = 0
	}
	fd.incref()
	defer fd.decref()
	e := syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l)
	return os.NewSyscallError("setsockopt", e)
}

type UnknownSocketError struct {
	sa syscall.Sockaddr
}

func (e *UnknownSocketError) String() string {
	return "unknown socket address type " + reflect.Typeof(e.sa).String()
}

func sockaddrToString(sa syscall.Sockaddr) (name string, err os.Error) {
	switch a := sa.(type) {
	case *syscall.SockaddrInet4:
		return joinHostPort(IP(&a.Addr).String(), itoa(a.Port)), nil
	case *syscall.SockaddrInet6:
		return joinHostPort(IP(&a.Addr).String(), itoa(a.Port)), nil
	case *syscall.SockaddrUnix:
		return a.Name, nil
	}

	return "", &UnknownSocketError{sa}
}
