/*
 * Copyright 2019-present Open Networking Foundation
 *
 * 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.p4runtime.ctl.client;

import com.google.common.util.concurrent.Futures;
import io.grpc.stub.StreamObserver;
import org.onosproject.net.pi.model.PiActionProfileId;
import org.onosproject.net.pi.model.PiCounterId;
import org.onosproject.net.pi.model.PiMeterId;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiTableId;
import org.onosproject.net.pi.runtime.PiHandle;
import org.onosproject.p4runtime.api.P4RuntimeReadClient;
import org.onosproject.p4runtime.ctl.codec.CodecException;
import org.onosproject.p4runtime.ctl.utils.P4InfoBrowser;
import org.onosproject.p4runtime.ctl.utils.PipeconfHelper;
import org.slf4j.Logger;
import p4.v1.P4RuntimeOuterClass;

import java.util.concurrent.CompletableFuture;

import static com.google.common.base.Preconditions.checkNotNull;
import static java.lang.String.format;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static org.onosproject.p4runtime.ctl.client.P4RuntimeClientImpl.SHORT_TIMEOUT_SECONDS;
import static org.onosproject.p4runtime.ctl.codec.Codecs.CODECS;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Handles the creation of P4Runtime ReadRequest and execution of the Read RPC
 * on the server.
 */
public final class ReadRequestImpl implements P4RuntimeReadClient.ReadRequest {

    private static final Logger log = getLogger(ReadRequestImpl.class);

    private final P4RuntimeClientImpl client;
    private final PiPipeconf pipeconf;
    private final P4RuntimeOuterClass.ReadRequest.Builder requestMsg;

    ReadRequestImpl(P4RuntimeClientImpl client, long p4DeviceId, PiPipeconf pipeconf) {
        this.client = client;
        this.pipeconf = pipeconf;
        this.requestMsg = P4RuntimeOuterClass.ReadRequest.newBuilder()
                .setDeviceId(p4DeviceId);
    }

    @Override
    public P4RuntimeReadClient.ReadRequest handles(Iterable<? extends PiHandle> handles) {
        checkNotNull(handles);
        handles.forEach(this::handle);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest tableEntries(Iterable<PiTableId> tableIds) {
        checkNotNull(tableIds);
        tableIds.forEach(this::tableEntries);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest defaultTableEntry(Iterable<PiTableId> tableIds) {
        checkNotNull(tableIds);
        tableIds.forEach(this::defaultTableEntry);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest actionProfileGroups(Iterable<PiActionProfileId> actionProfileIds) {
        checkNotNull(actionProfileIds);
        actionProfileIds.forEach(this::actionProfileGroups);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest actionProfileMembers(Iterable<PiActionProfileId> actionProfileIds) {
        checkNotNull(actionProfileIds);
        actionProfileIds.forEach(this::actionProfileMembers);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest counterCells(Iterable<PiCounterId> counterIds) {
        checkNotNull(counterIds);
        counterIds.forEach(this::counterCells);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest directCounterCells(Iterable<PiTableId> tableIds) {
        checkNotNull(tableIds);
        tableIds.forEach(this::directCounterCells);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest meterCells(Iterable<PiMeterId> meterIds) {
        checkNotNull(meterIds);
        meterIds.forEach(this::meterCells);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest directMeterCells(Iterable<PiTableId> tableIds) {
        checkNotNull(tableIds);
        tableIds.forEach(this::directMeterCells);
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest handle(PiHandle handle) {
        checkNotNull(handle);
        try {
            requestMsg.addEntities(CODECS.handle().encode(handle, null, pipeconf));
        } catch (CodecException e) {
            log.warn("Unable to read {} from {}: {} [{}]",
                     handle.entityType(), client.deviceId(), e.getMessage(), handle);
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest tableEntries(PiTableId tableId) {
        try {
            doTableEntry(tableId, false);
        } catch (InternalRequestException e) {
            log.warn("Unable to read entries for table '{}' from {}: {}",
                     tableId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest defaultTableEntry(PiTableId tableId) {
        try {
            doTableEntry(tableId, true);
        } catch (InternalRequestException e) {
            log.warn("Unable to read default entry for table '{}' from {}: {}",
                     tableId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest actionProfileGroups(PiActionProfileId actionProfileId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setActionProfileGroup(
                                    P4RuntimeOuterClass.ActionProfileGroup.newBuilder()
                                            .setActionProfileId(
                                                    p4ActionProfileId(actionProfileId))
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read groups for action profile '{}' from {}: {}",
                     actionProfileId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest actionProfileMembers(PiActionProfileId actionProfileId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setActionProfileMember(
                                    P4RuntimeOuterClass.ActionProfileMember.newBuilder()
                                            .setActionProfileId(
                                                    p4ActionProfileId(actionProfileId))
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read members for action profile '{}' from {}: {}",
                     actionProfileId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest counterCells(PiCounterId counterId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setCounterEntry(
                                    P4RuntimeOuterClass.CounterEntry.newBuilder()
                                            .setCounterId(p4CounterId(counterId))
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read cells for counter '{}' from {}: {}",
                     counterId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest meterCells(PiMeterId meterId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setMeterEntry(
                                    P4RuntimeOuterClass.MeterEntry.newBuilder()
                                            .setMeterId(p4MeterId(meterId))
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read cells for meter '{}' from {}: {}",
                     meterId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest directCounterCells(PiTableId tableId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setDirectCounterEntry(
                                    P4RuntimeOuterClass.DirectCounterEntry.newBuilder()
                                            .setTableEntry(
                                                    P4RuntimeOuterClass.TableEntry
                                                            .newBuilder()
                                                            .setTableId(p4TableId(tableId))
                                                            .build())
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read direct counter cells for table '{}' from {}: {}",
                     tableId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    @Override
    public P4RuntimeReadClient.ReadRequest directMeterCells(PiTableId tableId) {
        try {
            requestMsg.addEntities(
                    P4RuntimeOuterClass.Entity.newBuilder()
                            .setDirectMeterEntry(
                                    P4RuntimeOuterClass.DirectMeterEntry.newBuilder()
                                            .setTableEntry(
                                                    P4RuntimeOuterClass.TableEntry
                                                            .newBuilder()
                                                            .setTableId(p4TableId(tableId))
                                                            .build())
                                            .build())
                            .build());
        } catch (InternalRequestException e) {
            log.warn("Unable to read direct meter cells for table '{}' from {}: {}",
                     tableId, client.deviceId(), e.getMessage());
        }
        return this;
    }

    private void doTableEntry(PiTableId piTableId, boolean defaultEntries)
            throws InternalRequestException {
        checkNotNull(piTableId);
        final var builder = P4RuntimeOuterClass.TableEntry.newBuilder()
                .setTableId(p4TableId(piTableId))
                .setIsDefaultAction(defaultEntries);
        if (tableHasCounters(piTableId)) {
            builder.setCounterData(P4RuntimeOuterClass.CounterData
                                           .getDefaultInstance());
        }
        final var entityMsg = P4RuntimeOuterClass.Entity
                .newBuilder().setTableEntry(builder.build()).build();
        requestMsg.addEntities(entityMsg);
    }

    @Override
    public CompletableFuture<P4RuntimeReadClient.ReadResponse> submit() {
        final P4RuntimeOuterClass.ReadRequest readRequest = requestMsg.build();
        log.debug("Sending read request to {} for {} entities...",
                  client.deviceId(), readRequest.getEntitiesCount());
        if (readRequest.getEntitiesCount() == 0) {
            // No need to ask the server.
            return completedFuture(ReadResponseImpl.EMPTY);
        }
        final CompletableFuture<P4RuntimeReadClient.ReadResponse> future =
                new CompletableFuture<>();
        // Instantiate response builder and let stream observer populate it.
        final ReadResponseImpl.Builder responseBuilder =
                ReadResponseImpl.builder(client.deviceId(), pipeconf);
        final StreamObserver<P4RuntimeOuterClass.ReadResponse> observer =
                new StreamObserver<P4RuntimeOuterClass.ReadResponse>() {
                    @Override
                    public void onNext(P4RuntimeOuterClass.ReadResponse value) {
                        log.debug("Received read response from {} with {} entities...",
                                  client.deviceId(), value.getEntitiesCount());
                        value.getEntitiesList().forEach(responseBuilder::addEntity);
                    }
                    @Override
                    public void onError(Throwable t) {
                        client.handleRpcError(t, "READ");
                        // TODO: implement parsing of trailer errors
                        future.complete(responseBuilder.fail(t));
                    }
                    @Override
                    public void onCompleted() {
                        future.complete(responseBuilder.build());
                    }
                };
        client.execRpc(s -> s.read(readRequest, observer), SHORT_TIMEOUT_SECONDS);
        return future;
    }

    @Override
    public P4RuntimeReadClient.ReadResponse submitSync() {
        return Futures.getUnchecked(submit());
    }

    private int p4TableId(PiTableId piTableId) throws InternalRequestException {
        try {
            return getBrowser().tables().getByName(piTableId.id())
                    .getPreamble().getId();
        } catch (P4InfoBrowser.NotFoundException e) {
            throw new InternalRequestException(e.getMessage());
        }
    }

    private boolean tableHasCounters(PiTableId piTableId) throws InternalRequestException {
        return pipeconf.pipelineModel().table(piTableId).orElseThrow(
                () -> new InternalRequestException(format(
                        "Not such a table in pipeline model: %s", piTableId)))
                .counters().size() > 0;
    }

    private int p4ActionProfileId(PiActionProfileId piActionProfileId)
            throws InternalRequestException {
        try {
            return getBrowser().actionProfiles().getByName(piActionProfileId.id())
                    .getPreamble().getId();
        } catch (P4InfoBrowser.NotFoundException e) {
            throw new InternalRequestException(e.getMessage());
        }
    }

    private int p4CounterId(PiCounterId counterId)
            throws InternalRequestException {
        try {
            return getBrowser().counters().getByName(counterId.id())
                    .getPreamble().getId();
        } catch (P4InfoBrowser.NotFoundException e) {
            throw new InternalRequestException(e.getMessage());
        }
    }

    private int p4MeterId(PiMeterId meterId)
            throws InternalRequestException {
        try {
            return getBrowser().meters().getByName(meterId.id())
                    .getPreamble().getId();
        } catch (P4InfoBrowser.NotFoundException e) {
            throw new InternalRequestException(e.getMessage());
        }
    }

    private P4InfoBrowser getBrowser() throws InternalRequestException {
        final P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);
        if (browser == null) {
            throw new InternalRequestException(
                    "Unable to get a P4Info browser for pipeconf " + pipeconf.id());
        }
        return browser;
    }

    /**
     * Internal exception to signal that something went wrong when populating
     * the request.
     */
    private final class InternalRequestException extends Exception {

        private InternalRequestException(String message) {
            super(message);
        }
    }
}
