// Copyright 2011 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 net

import (
	"errors"
	"io"
	"os"
	"syscall"
)

func (fd *netFD) status(ln int) (string, error) {
	if !fd.ok() {
		return "", syscall.EINVAL
	}

	status, err := os.Open(fd.dir + "/status")
	if err != nil {
		return "", err
	}
	defer status.Close()
	buf := make([]byte, ln)
	n, err := io.ReadFull(status, buf[:])
	if err != nil {
		return "", err
	}
	return string(buf[:n]), nil
}

func newFileFD(f *os.File) (net *netFD, err error) {
	var ctl *os.File
	close := func(fd int) {
		if err != nil {
			syscall.Close(fd)
		}
	}

	path, err := syscall.Fd2path(int(f.Fd()))
	if err != nil {
		return nil, os.NewSyscallError("fd2path", err)
	}
	comp := splitAtBytes(path, "/")
	n := len(comp)
	if n < 3 || comp[0][0:3] != "net" {
		return nil, syscall.EPLAN9
	}

	name := comp[2]
	switch file := comp[n-1]; file {
	case "ctl", "clone":
		syscall.ForkLock.RLock()
		fd, err := syscall.Dup(int(f.Fd()), -1)
		syscall.ForkLock.RUnlock()
		if err != nil {
			return nil, os.NewSyscallError("dup", err)
		}
		defer close(fd)

		dir := netdir + "/" + comp[n-2]
		ctl = os.NewFile(uintptr(fd), dir+"/"+file)
		ctl.Seek(0, 0)
		var buf [16]byte
		n, err := ctl.Read(buf[:])
		if err != nil {
			return nil, err
		}
		name = string(buf[:n])
	default:
		if len(comp) < 4 {
			return nil, errors.New("could not find control file for connection")
		}
		dir := netdir + "/" + comp[1] + "/" + name
		ctl, err = os.OpenFile(dir+"/ctl", os.O_RDWR, 0)
		if err != nil {
			return nil, err
		}
		defer close(int(ctl.Fd()))
	}
	dir := netdir + "/" + comp[1] + "/" + name
	laddr, err := readPlan9Addr(comp[1], dir+"/local")
	if err != nil {
		return nil, err
	}
	return newFD(comp[1], name, ctl, nil, laddr, nil)
}

func newFileConn(f *os.File) (c Conn, err error) {
	fd, err := newFileFD(f)
	if err != nil {
		return nil, err
	}
	if !fd.ok() {
		return nil, syscall.EINVAL
	}

	fd.data, err = os.OpenFile(fd.dir+"/data", os.O_RDWR, 0)
	if err != nil {
		return nil, err
	}

	switch fd.laddr.(type) {
	case *TCPAddr:
		return newTCPConn(fd), nil
	case *UDPAddr:
		return newUDPConn(fd), nil
	}
	return nil, syscall.EPLAN9
}

func newFileListener(f *os.File) (l Listener, err error) {
	fd, err := newFileFD(f)
	if err != nil {
		return nil, err
	}
	switch fd.laddr.(type) {
	case *TCPAddr:
	default:
		return nil, syscall.EPLAN9
	}

	// check that file corresponds to a listener
	s, err := fd.status(len("Listen"))
	if err != nil {
		return nil, err
	}
	if s != "Listen" {
		return nil, errors.New("file does not represent a listener")
	}

	return &TCPListener{fd}, nil
}

// FileConn returns a copy of the network connection corresponding to
// the open file f.  It is the caller's responsibility to close f when
// finished.  Closing c does not affect f, and closing f does not
// affect c.
func FileConn(f *os.File) (c Conn, err error) {
	return newFileConn(f)
}

// FileListener returns a copy of the network listener corresponding
// to the open file f.  It is the caller's responsibility to close l
// when finished.  Closing l does not affect f, and closing f does not
// affect l.
func FileListener(f *os.File) (l Listener, err error) {
	return newFileListener(f)
}

// FilePacketConn returns a copy of the packet network connection
// corresponding to the open file f.  It is the caller's
// responsibility to close f when finished.  Closing c does not affect
// f, and closing f does not affect c.
func FilePacketConn(f *os.File) (c PacketConn, err error) {
	return nil, syscall.EPLAN9
}
