/*
 * Copyright (c) 2002-2010 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 *  the terms of the license agreement you entered into with JSCAPE.
 */

package com.jscape.util.net.socket;

import com.jscape.util.net.ConnectionDescriptor;
import com.jscape.util.net.TransportAddress;
import com.jscape.util.net.connection.AsyncConnector;
import com.jscape.util.net.connection.Connector;
import com.jscape.util.net.connection.SyncRawConnection;
import com.jscape.util.service.AbstractService;

import java.util.concurrent.ExecutorService;

import static com.jscape.util.Parameters.assertNotNull;

/**
 * @author Alex Usun
 */
public class SocketAsyncConnector
        extends AbstractService<AsyncConnector.Listener<SyncRawConnection>>
        implements AsyncConnector<SyncRawConnection> {

    private final SocketConnector base;
    private final ExecutorService executorService;

    public static SocketAsyncConnector connectorFor(ConnectionDescriptor descriptor, ExecutorService executorService) {
        return new SocketAsyncConnector(new SocketConnector(descriptor), executorService);
    }

    public SocketAsyncConnector(SocketConnector base, ExecutorService executorService) {
        assertNotNull(base);
        this.base = base;

        assertNotNull(executorService);
        this.executorService = executorService;
    }

    public TransportAddress boundAddress() {
        return null;
    }

    @Override
    public String toString() {
        return "SocketAsyncConnector {"
               + "base=" + this.base
               + ", executorService=" + this.executorService
               + '}';
    }

    @Override
    protected void actualStart()
            throws Exception {
        this.executorService.submit(SocketAsyncConnector.this::run);
    }

    protected void run() {
        try {
            SyncRawConnection connection = this.base.connect();
            this.context.onConnection(this, connection);
        } catch (Exception e) {
            this.context.onError(this, new Connector.OperationException(e));
        }
    }

}