package com.lheinrich.lotuscloud.api.network;

import com.lheinrich.lotuscloud.api.crypt.Crypter;
import com.lheinrich.lotuscloud.api.packet.ErrorPacket;

import javax.crypto.SecretKey;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.security.KeyPair;
import java.security.PublicKey;

/**
 * Copyright (c) 2017 Lennart Heinrich (www.lheinrich.com)
 */
public class PacketClient {

    public static Packet request(String host, int port, Packet packet) {
        KeyPair keyPair = Crypter.generateKeyPair();

        try {
            Socket socket = new Socket(host, port);

            if (socket.isClosed()) {
                return new ErrorPacket("socket closed");
            }

            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());

            out.writeObject(keyPair.getPublic());
            PublicKey publicKey = (PublicKey) in.readObject();

            SecretKey key = Crypter.generateEC(keyPair.getPrivate(), publicKey);

            out.writeObject(Crypter.encrypt(key, Crypter.toByteArray(packet)));
            out.flush();

            Packet response = (Packet) Crypter.toObject(Crypter.decrypt(key, (byte[]) in.readObject()));

            in.close();
            out.close();
            socket.close();

            return response;
        } catch (Exception ex) {
            return new ErrorPacket(ex.getMessage());
        }
    }
}