/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.incubator.rpc.grpc;

import static org.onosproject.incubator.rpc.grpc.GrpcDeviceUtils.asMap;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.onosproject.grpc.Link.LinkDetectedMsg;
import org.onosproject.grpc.Link.LinkType;
import org.onosproject.grpc.Link.LinkVanishedMsg;
import org.onosproject.grpc.Link.Void;
import org.onosproject.grpc.LinkProviderServiceRpcGrpc;
import org.onosproject.grpc.LinkProviderServiceRpcGrpc.LinkProviderServiceRpcFutureStub;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Link.Type;
import org.onosproject.net.link.LinkDescription;
import org.onosproject.net.link.LinkProvider;
import org.onosproject.net.link.LinkProviderService;
import org.onosproject.net.provider.AbstractProviderService;
import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.api.client.repackaged.com.google.common.annotations.Beta;
import com.google.common.util.concurrent.ListenableFuture;

import io.grpc.Channel;

/**
 * Proxy object to handle LinkProviderService calls.
 *
 * RPC wise, this will initiate a RPC call on each method invocation.
 */
@Beta
class LinkProviderServiceClientProxy
    extends AbstractProviderService<LinkProvider>
    implements LinkProviderService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    private final Channel channel;

    /**
     * Constructs {@link LinkProviderServiceClientProxy}.
     *
     * @param provider {@link LinkProvider}. Only ProviderId scheme is used.
     * @param channel channel to use to call RPC
     */
    protected LinkProviderServiceClientProxy(LinkProvider provider, Channel channel) {
        super(provider);
        this.channel = channel;
    }

    @Override
    public void linkDetected(LinkDescription linkDescription) {
        checkValidity();

        LinkProviderServiceRpcFutureStub newStub = LinkProviderServiceRpcGrpc.newFutureStub(channel);
        ListenableFuture<Void> future = newStub.linkDetected(detectMsg(provider().id(), linkDescription));

        try {
            // There's no need to wait, but just checking server
            future.get(500, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("linkDetected({}) failed", linkDescription, e);
            invalidate();
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error("linkDetected({}) failed", linkDescription, e);
            invalidate();
        } catch (TimeoutException e) {
            log.error("linkDetected({}) failed", linkDescription, e);
            invalidate();
        }
    }

    @Override
    public void linkVanished(LinkDescription linkDescription) {
        checkValidity();

        LinkProviderServiceRpcFutureStub newStub = LinkProviderServiceRpcGrpc.newFutureStub(channel);
        ListenableFuture<Void> future = newStub.linkVanished(vanishMsg(provider().id(), linkDescription));

        try {
            // There's no need to wait, but just checking server
            future.get(500, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("linkVanished({}) failed", linkDescription, e);
            invalidate();
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error("linkVanished({}) failed", linkDescription, e);
            invalidate();
        } catch (TimeoutException e) {
            log.error("linkVanished({}) failed", linkDescription, e);
            invalidate();
        }
    }

    @Override
    public void linksVanished(ConnectPoint connectPoint) {
        checkValidity();

        LinkProviderServiceRpcFutureStub newStub = LinkProviderServiceRpcGrpc.newFutureStub(channel);
        ListenableFuture<Void> future = newStub.linkVanished(vanishMsg(provider().id(), connectPoint));

        try {
            // There's no need to wait, but just checking server
            future.get(500, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("linksVanished({}) failed", connectPoint, e);
            invalidate();
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error("linksVanished({}) failed", connectPoint, e);
            invalidate();
        } catch (TimeoutException e) {
            log.error("linksVanished({}) failed", connectPoint, e);
            invalidate();
        }
    }

    @Override
    public void linksVanished(DeviceId deviceId) {
        checkValidity();

        LinkProviderServiceRpcFutureStub newStub = LinkProviderServiceRpcGrpc.newFutureStub(channel);
        ListenableFuture<Void> future = newStub.linkVanished(vanishMsg(provider().id(), deviceId));

        try {
            // There's no need to wait, but just checking server
            future.get(500, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            log.error("linksVanished({}) failed", deviceId, e);
            invalidate();
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            log.error("linksVanished({}) failed", deviceId, e);
            invalidate();
        } catch (TimeoutException e) {
            log.error("linksVanished({}) failed", deviceId, e);
            invalidate();
        }
    }

    /**
     * Builds {@link LinkDetectedMsg}.
     *
     * @param id ProviderId
     * @param linkDescription {@link LinkDescription}
     * @return {@link LinkDetectedMsg}
     */
    private LinkDetectedMsg detectMsg(ProviderId id,
                                      LinkDescription linkDescription) {
        LinkDetectedMsg.Builder builder = LinkDetectedMsg.newBuilder();
        builder.setProviderId(id.scheme())
               .setLinkDescription(builder.getLinkDescriptionBuilder()
                                    .setSrc(translate(linkDescription.src()))
                                    .setDst(translate(linkDescription.dst()))
                                    .setType(translate(linkDescription.type()))
                                    .putAllAnnotations(asMap(linkDescription.annotations()))
                                    .build()
                                    );
        return builder.build();
    }

    /**
     * Builds {@link LinkVanishedMsg}.
     *
     * @param id ProviderId
     * @param linkDescription {@link LinkDescription}
     * @return {@link LinkVanishedMsg}
     */
    private LinkVanishedMsg vanishMsg(ProviderId id,
                                      LinkDescription linkDescription) {

        LinkVanishedMsg.Builder builder = LinkVanishedMsg.newBuilder();
        builder.setProviderId(id.scheme())
            .setLinkDescription(builder.getLinkDescriptionBuilder()
                             .setSrc(translate(linkDescription.src()))
                             .setDst(translate(linkDescription.dst()))
                             .setType(translate(linkDescription.type()))
                             .putAllAnnotations(asMap(linkDescription.annotations()))
                             .build()
                             );
        return builder.build();
    }

    /**
     * Builds {@link LinkVanishedMsg}.
     *
     * @param id ProviderId
     * @param connectPoint {@link ConnectPoint}
     * @return {@link LinkVanishedMsg}
     */
    private LinkVanishedMsg vanishMsg(ProviderId id,
                                      ConnectPoint connectPoint) {

        LinkVanishedMsg.Builder builder = LinkVanishedMsg.newBuilder();
        builder.setProviderId(id.scheme())
            .setConnectPoint(translate(connectPoint));
        return builder.build();
    }

    /**
     * Builds {@link LinkVanishedMsg}.
     *
     * @param id ProviderId
     * @param deviceId {@link DeviceId}
     * @return {@link LinkVanishedMsg}
     */
    private LinkVanishedMsg vanishMsg(ProviderId id, DeviceId deviceId) {

        LinkVanishedMsg.Builder builder = LinkVanishedMsg.newBuilder();
        builder.setProviderId(id.scheme())
            .setDeviceId(deviceId.toString());
        return builder.build();
    }

    /**
     * Translates ONOS object to gRPC message.
     *
     * @param type {@link Link.Type}
     * @return gRPC LinkType
     */
    private LinkType translate(Type type) {
        switch (type) {
        case DIRECT:
            return LinkType.DIRECT;
        case EDGE:
            return LinkType.EDGE;
        case INDIRECT:
            return LinkType.INDIRECT;
        case OPTICAL:
            return LinkType.OPTICAL;
        case TUNNEL:
            return LinkType.TUNNEL;
        case VIRTUAL:
            return LinkType.VIRTUAL;

        default:
            return LinkType.DIRECT;

        }
    }

    /**
     * Translates ONOS object to gRPC message.
     *
     * @param cp {@link ConnectPoint}
     * @return gRPC ConnectPoint
     */
    private org.onosproject.grpc.Link.ConnectPoint translate(ConnectPoint cp) {
        return org.onosproject.grpc.Link.ConnectPoint.newBuilder()
                .setDeviceId(cp.deviceId().toString())
                .setPortNumber(cp.port().toString())
                .build();
    }

}
