// Copyright 2015 The Chromium 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 main

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"time"

	"golang.org/x/mobile/app"

	"mojo/public/go/application"
	"mojo/public/go/bindings"
	"mojo/public/go/system"

	"mojo/services/network/public/interfaces/net_address"
	"mojo/services/network/public/interfaces/network_service"
	"mojo/services/network/public/interfaces/tcp_bound_socket"
	"mojo/services/network/public/interfaces/tcp_connected_socket"
	"mojo/services/network/public/interfaces/tcp_server_socket"
)

//#include "mojo/public/c/system/types.h"
import "C"

type MojoConnection struct {
	sendStream    system.ProducerHandle
	receiveStream system.ConsumerHandle
	socket        system.MessagePipeHandle
	localAddr     net.Addr
	remoteAddr    net.Addr
}

// Implements net.Conn.
func (c *MojoConnection) Read(b []byte) (int, error) {
	l := len(b)
	r, read := c.receiveStream.BeginReadData(l, system.MOJO_READ_DATA_FLAG_NONE)
	if r != system.MOJO_RESULT_OK {
		return 0, fmt.Errorf("can't read %v bytes: %v", l, r)
	}
	if l > len(read) {
		l = len(read)
	}
	copy(b, read[:l])
	if r := c.receiveStream.EndReadData(l); r != system.MOJO_RESULT_OK {
		return 0, fmt.Errorf("can't read %v bytes: %v", l, r)
	}
	return l, nil
}

// Implements net.Conn.
func (c *MojoConnection) Write(b []byte) (int, error) {
	l := len(b)
	r, buf := c.sendStream.BeginWriteData(l, system.MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)
	if r != system.MOJO_RESULT_OK {
		return 0, fmt.Errorf("can't write %v bytes: %v", l, r)
	}
	copy(buf, b)
	if r := c.sendStream.EndWriteData(l); r != system.MOJO_RESULT_OK {
		return 0, fmt.Errorf("can't write %v bytes: %v", l, r)
	}
	return l, nil
}

// Implements net.Conn.
func (c *MojoConnection) Close() error {
	c.sendStream.Close()
	c.receiveStream.Close()
	c.socket.Close()
	return nil
}

// Implements net.Conn.
func (c *MojoConnection) LocalAddr() net.Addr {
	return c.localAddr
}

// Implements net.Conn.
func (c *MojoConnection) RemoteAddr() net.Addr {
	return c.remoteAddr
}

// Implements net.Conn.
func (c *MojoConnection) SetDeadline(t time.Time) error {
	if err := c.SetReadDeadline(t); err != nil {
		return err
	}
	return c.SetWriteDeadline(t)
}

// Implements net.Conn.
func (c *MojoConnection) SetReadDeadline(t time.Time) error {
	// Do nothing.
	return nil
}

// Implements net.Conn.
func (c *MojoConnection) SetWriteDeadline(t time.Time) error {
	// Do nothing.
	return nil
}

type MojoListener struct {
	serverSocket *tcp_server_socket.TcpServerSocketProxy
}

// Implements net.Listener.
func (l *MojoListener) Accept() (net.Conn, error) {
	r, sendProducer, sendConsumer := system.GetCore().CreateDataPipe(nil)
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create data pipe: %v", r))
	}
	r, receiveProducer, receiveConsumer := system.GetCore().CreateDataPipe(nil)
	if r != system.MOJO_RESULT_OK {
		panic(fmt.Sprintf("can't create data pipe: %v", r))
	}
	request, pointer := tcp_connected_socket.CreateMessagePipeForTcpConnectedSocket()
	networkError, remoteAddress, err := l.serverSocket.Accept(sendConsumer, receiveProducer, request)
	if err != nil {
		return nil, err
	}
	if networkError.Code != 0 {
		return nil, fmt.Errorf("%s", *networkError.Description)
	}

	var addr net.Addr
	if remoteAddress.Ipv4 != nil {
		addr = &net.TCPAddr{
			IP:   remoteAddress.Ipv4.Addr[:4],
			Port: int(remoteAddress.Ipv4.Port),
		}
	} else {
		addr = &net.TCPAddr{
			IP:   remoteAddress.Ipv6.Addr[:16],
			Port: int(remoteAddress.Ipv6.Port),
		}
	}
	return &MojoConnection{
		sendProducer,
		receiveConsumer,
		pointer.PassMessagePipe(),
		l.Addr(),
		addr,
	}, nil
}

// Implements net.Listener.
func (l *MojoListener) Close() error {
	l.serverSocket.Close_proxy()
	return nil
}

// Implements net.Listener.
func (l *MojoListener) Addr() net.Addr {
	return &net.TCPAddr{
		IP:   []byte{127, 0, 0, 1},
		Port: 8080,
	}
}

type HttpServerDelegate struct {
	networkService *network_service.NetworkServiceProxy
	tcpBoundSocket *tcp_bound_socket.TcpBoundSocketProxy
	serverSocket   *tcp_server_socket.TcpServerSocketProxy
}

func (d *HttpServerDelegate) InitTCPBoundSocket() error {
	addr := &net_address.NetAddress{
		net_address.NetAddressFamily_IpV4,
		&net_address.NetAddressIPv4{
			8080,
			[4]uint8{127, 0, 0, 1},
		},
		nil,
	}
	request, pointer := tcp_bound_socket.CreateMessagePipeForTcpBoundSocket()
	networkError, _, err := d.networkService.CreateTcpBoundSocket(addr, request)
	if err != nil {
		return err
	}
	if networkError.Code != 0 {
		return fmt.Errorf("%s", *networkError.Description)
	}
	d.tcpBoundSocket = tcp_bound_socket.NewTcpBoundSocketProxy(pointer, bindings.GetAsyncWaiter())
	return nil
}

func (d *HttpServerDelegate) InitServerSocket() error {
	request, pointer := tcp_server_socket.CreateMessagePipeForTcpServerSocket()
	networkError, err := d.tcpBoundSocket.StartListening(request)
	if err != nil {
		return err
	}
	if networkError.Code != 0 {
		return fmt.Errorf("%s", *networkError.Description)
	}
	d.serverSocket = tcp_server_socket.NewTcpServerSocketProxy(pointer, bindings.GetAsyncWaiter())
	return nil
}

func (d *HttpServerDelegate) Initialize(ctx application.Context) {
	request, pointer := network_service.CreateMessagePipeForNetworkService()
	ctx.ConnectToApplication("mojo:network_service").ConnectToService(&request)
	d.networkService = network_service.NewNetworkServiceProxy(pointer, bindings.GetAsyncWaiter())

	if err := d.InitTCPBoundSocket(); err != nil {
		log.Printf("can't create TCP socket: %v\n", err)
		return
	}
	if err := d.InitServerSocket(); err != nil {
		log.Printf("can't create server socket: %v\n", err)
		return
	}

	http.HandleFunc("/go", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, Go http server!")
	})
	l := &MojoListener{d.serverSocket}
	if err := http.Serve(l, nil); err != nil {
		log.Printf("can't serve request: %v\n", err)
		return
	}
}

func (d *HttpServerDelegate) AcceptConnection(c *application.Connection) {
	c.Close()
}

func (d *HttpServerDelegate) Quit() {
	d.networkService.Close_proxy()
	d.tcpBoundSocket.Close_proxy()
	d.serverSocket.Close_proxy()
}

//export MojoMain
func MojoMain(handle C.MojoHandle) C.MojoResult {
	application.Run(&HttpServerDelegate{}, system.MojoHandle(handle))
	return C.MOJO_RESULT_OK
}

func main() {
	app.Run(app.Callbacks{})
}
