/*
 * Copyright (c) 2017 NumberFour AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   NumberFour AG - Initial API and implementation
 */


import {IDuplex, Duplex} from "stream";
export external public interface ~ISocket extends IDuplex {
    // Extended base methods
    public connect(portOrPath: union{number, string}
            , hostOrConnectionListener: union{string, Function}=, connectionListener: Function=): void;
    public bufferSize: number;
    public destroy(): void;
    public setTimeout(timeout: number, callback: Function=): void;
    public setNoDelay(noDelay: boolean=): void;
    public setKeepAlive(enable: boolean=, initialDelay: number=): void;
    public address(): ~Object with { port: number; family: string; address: string; };
    public unref(): void;
    public ref(): void;

    public remoteAddress: string;
    public remoteFamily: string;
    public remotePort: number;
    public localAddress: string;
    public localPort: number;
    public bytesRead: number;
    public bytesWritten: number;

    // Extended base methods
    @Override public end(data: any=, encoding: string=, cb: Function=): void;
}

export external public class Socket extends Duplex implements ISocket {
    public constructor (options: ~Object with {fd?: string; type?: string; allowHalfOpen?: boolean; });
    // Extended base methods
    @Override public connect(portOrPath: union{number, string}
            , hostOrConnectionListener: union{string, Function}=, connectionListener: Function=): void;
    @Override public bufferSize: number;
    @Override public destroy(): void;
    @Override public setTimeout(timeout: number, callback: Function=): void;
    @Override public setNoDelay(noDelay: boolean=): void;
    @Override public setKeepAlive(enable: boolean=, initialDelay: number=): void;
    @Override public address(): ~Object with { port: number; family: string; address: string; };
    @Override public unref(): void;
    @Override public ref(): void;

    @Override public remoteAddress: string;
    @Override public remoteFamily: string;
    @Override public remotePort: number;
    @Override public localAddress: string;
    @Override public localPort: number;
    @Override public bytesRead: number;
    @Override public bytesWritten: number;

    // Extended base methods
    @Override public end(data: any=, encoding: string=, cb: Function=): void;
};

export external public interface ~IServer extends ISocket {
    public listen(port: number, host: string=, backlog: number=, listeningListener: Function=): this;
    public close(callback: Function=): this;
    public maxConnections: number;
    public connections: number;
}
interface ~ConnectOptions {
    public port: number;
    public host?: string;
    public localAddress?: string;
    public localPort?: string;
    public family?: number;
    public allowHalfOpen?: boolean;
}

export external public function createServer(options: ~Object with { allowHalfOpen?: boolean; }=, connectionListener: {function(socket: Socket)}=): IServer;
export external public function connect(options: ~ConnectOptions, connectionListener: Function=): Socket;
export external public function createConnection(options: ~ConnectOptions, connectionListener: Function=): Socket;
export external public function isIP(input: string): number;
export external public function isIPv4(input: string): boolean;
export external public function isIPv6(input: string): boolean;


