/*
 * This file is part of RPooli.
 *
 * RPooli is free software: you can redistribute it and/or modify
 * it under the terms of the Apache License as published by
 * The Apache Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Apache License for more details.
 *
 * You should have received a copy of the Apache License
 * along with RPooli.  If not, see <http://www.apache.org/licenses/>.
 */

package eu.openanalytics.rpooli.api;

import static eu.openanalytics.rpooli.api.spec.resource.Nodes.GetNodesByNodeIdResponse.withJsonOK;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;

import javax.ws.rs.WebApplicationException;

import org.apache.commons.lang3.Validate;

import org.eclipse.statet.rj.servi.pool.PoolNodeItem;

import eu.openanalytics.rpooli.AbstractRPooliServerAware;
import eu.openanalytics.rpooli.ClientSimulator;
import eu.openanalytics.rpooli.RPooliNode;
import eu.openanalytics.rpooli.RPooliServer;
import eu.openanalytics.rpooli.api.spec.model.ErrorJson;
import eu.openanalytics.rpooli.api.spec.model.Node;
import eu.openanalytics.rpooli.api.spec.model.NodesJson;
import eu.openanalytics.rpooli.api.spec.resource.Nodes;

/**
 * @author "OpenAnalytics &lt;rsb.development@openanalytics.eu&gt;"
 */
public class NodesResource extends AbstractRPooliServerAware implements Nodes
{
    private static final String NO_AUTH_CONFIG = "none";

    private final ClientSimulator clientSimulator;

    public NodesResource(final RPooliServer server, final ClientSimulator clientSimulator)
    {
        super(server);
        this.clientSimulator = Validate.notNull(clientSimulator);
    }

    @Override
    public GetNodesResponse getNodes() throws Exception
    {
        final NodesJson nodes = new NodesJson();

        for (final RPooliNode rpn : server.getNodes())
        {
            nodes.getNodes().add(buildNode(rpn));
        }

        return GetNodesResponse.withJsonOK(nodes);
    }

    @Override
    public GetNodesByNodeIdResponse getNodesByNodeId(final String nodeId) throws Exception
    {
        final RPooliNode rpn = server.findNodeById(nodeId);
        return rpn == null
                          ? GetNodesByNodeIdResponse.withJsonNotFound(new ErrorJson().withError("Node not found: "
                                                                                                + nodeId))
                          : withJsonOK(buildNode(rpn));
    }

    @Override
    public DeleteNodesByNodeIdResponse deleteNodesByNodeId(final String nodeId, final boolean kill)
        throws Exception
    {
        getNodeOrDie(nodeId).getObject().evict(kill ? 0L : server.getConfig().getEvictionTimeout());

        return DeleteNodesByNodeIdResponse.withNoContent();
    }

    @Override
    public PostNodesByNodeIdConsoleResponse postNodesByNodeIdConsole(final String nodeId) throws Exception
    {
        getNodeOrDie(nodeId).getObject().getNodeHandler().enableConsole(NO_AUTH_CONFIG);

        return PostNodesByNodeIdConsoleResponse.withNoContent();
    }

    @Override
    public DeleteNodesByNodeIdConsoleResponse deleteNodesByNodeIdConsole(final String nodeId)
        throws Exception
    {
        getNodeOrDie(nodeId).getObject().getNodeHandler().disableConsole();

        return DeleteNodesByNodeIdConsoleResponse.withNoContent();
    }

    @Override
    public PostNodesTestResponse postNodesTest() throws Exception
    {
        clientSimulator.acquireNode();

        return PostNodesTestResponse.withNoContent();
    }

    @Override
    public DeleteNodesTestResponse deleteNodesTest() throws Exception
    {
        clientSimulator.releaseAllNodes();

        return DeleteNodesTestResponse.withNoContent();
    }

    private RPooliNode getNodeOrDie(final String nodeId)
    {
        final RPooliNode rpn = server.findNodeById(nodeId);
        if (rpn == null)
        {
            throw new WebApplicationException(NOT_FOUND);
        }
        return rpn;
    }

    private static Node buildNode(final RPooliNode rpn)
    {
        final PoolNodeItem pni = rpn.getItem();

        return new Node().withId(rpn.getId())
            .withAddress(rpn.getAddress())
            .withClientLabel(pni.getCurrentClientLabel())
            .withCreationTime(pni.getCreationTime())
            .withLentCount(pni.getUsageCount())
            .withLentDuration(pni.getUsageDuration())
            .withState(Node.State.fromValue(rpn.getItem().getState().toString()))
            .withStateTime(pni.getStateTime())
            .withConsoleEnabled(pni.isConsoleEnabled());
    }

}

@@ -976,16 +976,71 @@
 odeItem;
+%0Aimport org.eclipse.statet.rj.servi.pool.PoolNodeState;
 %0A%0Aimport
@@ -1450,16 +1450,17 @@
 Nodes;%0A%0A
+%0A
 /**%0A * @
@@ -4673,27 +4673,19 @@
 ate(
-Node.State.fromValu
+convertStat
 e(rp
@@ -4710,19 +4710,8 @@
 te()
-.toString()
 ))%0A 
@@ -4819,11 +4819,472 @@
 ;%0A    %7D%0A
+%09%0A%09private static Node.State convertState(final PoolNodeState state) %7B%0A%09%09switch (state) %7B%0A%09%09case INITIALIZING:%0A%09%09%09return Node.State.INITIALIZING;%0A%09%09case CHECKING:%0A%09%09%09return Node.State.CHECKING;%0A%09%09case IDLING:%0A%09%09%09return Node.State.IDLING;%0A%09%09case ALLOCATED:%0A%09%09%09return Node.State.ALLOCATED;%0A%09%09case DISPOSING:%0A%09%09%09return Node.State.EVICTING;%0A%09%09case DISPOSED:%0A%09%09%09return Node.State.DISPOSED;%0A%09%09default:%0A%09%09%09throw new IllegalArgumentException(state.toString());%0A%09%09%7D%0A%09%7D%0A%09
 %0A%7D%0A

Add support for node state DISPOSING added in RJ