package com.saki.service;

import com.saki.log.SQLog;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * @author Saki
 * @version 1.0
 */
public abstract class SocketClient extends Socket {
    private class Receiver implements Runnable {
        @Override
        public void run() {
            while (null != in) {
                try {
                    int len = in.readInt();
                    byte[] bin = new byte[len];
                    in.readFully(bin, 4, len - 4);
                    bin[0] = (byte) ((len >> 24) & 0xFF);
                    bin[1] = (byte) ((len >> 16) & 0xFF);
                    bin[2] = (byte) ((len >> 8) & 0xFF);
                    bin[3] = (byte) ((len >> 0) & 0xFF);
                    doReceive(bin);
                } catch (IOException e) {
                    error(e);
                    return;
                }
            }
        }
    }

    private DataInputStream in;
    private OutputStream out;
    private Thread read;
    public SocketClient(String addr, int port) throws UnknownHostException,
            IOException {
        super(addr, port);
        out = getOutputStream();
        in = new DataInputStream(getInputStream());
        read = new Thread(new Receiver());
        read.start();
    }
    public void destroy() {
        try {
            if (null != in) {
                in.close();
                in = null;
            }
            if (null != out) {
                out.close();
                out = null;
            }
            if(null != read) {
                read = null;
            }
            this.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public abstract void doReceive(byte[] byteArray);

    public void error(IOException e) {
        e.printStackTrace();
        destroy();
    }

    public void send(byte[] bin) {
        if (null != out) {
            try {
                out.write(bin);
                out.flush();
            } catch (IOException e) {
                error(e);
            }
        }
    }
}
