/*
 * 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.grpc.ctl;

import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ClientInterceptor;
import io.grpc.ForwardingClientCall;
import io.grpc.ForwardingClientCallListener;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;
import io.grpc.Status;
import io.grpc.protobuf.lite.ProtoLiteUtils;
import org.onosproject.grpc.api.GrpcChannelId;
import org.slf4j.Logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import static java.lang.String.format;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * gRPC client interceptor that logs to file all messages sent and received.
 */
final class GrpcLoggingInterceptor implements ClientInterceptor {

    private static final Metadata.Key<com.google.rpc.Status> GRPC_STATUS_KEY =
            Metadata.Key.of(
                    "grpc-status-details-bin",
                    ProtoLiteUtils.metadataMarshaller(
                            com.google.rpc.Status.getDefaultInstance()));

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

    private final AtomicLong callIdGenerator = new AtomicLong();
    private final GrpcChannelId channelId;
    private final AtomicBoolean enabled;

    private FileWriter writer;

    GrpcLoggingInterceptor(GrpcChannelId channelId, AtomicBoolean enabled) {
        this.channelId = channelId;
        this.enabled = enabled;
    }

    private boolean initWriter() {
        if (writer != null) {
            return true;
        }
        final String safeChName = channelId.id()
                .replaceAll("[^A-Za-z0-9]", "_");
        final String fileName = format("grpc_%s_", safeChName).toLowerCase();
        try {
            final File tmpFile = File.createTempFile(fileName, ".log");
            this.writer = new FileWriter(tmpFile);
            log.info("Created gRPC call log file for channel {}: {}",
                     channelId, tmpFile.getAbsolutePath());
            return true;
        } catch (IOException e) {
            log.error("Unable to initialize gRPC call log writer", e);
        }
        return false;
    }

    void close() {
        synchronized (this) {
            if (writer == null) {
                return;
            }
            try {
                log.info("Closing log writer for {}...", channelId);
                writer.close();
            } catch (IOException e) {
                log.error("Unable to close gRPC call log writer", e);
            }
            writer = null;
        }
    }

    private void write(String message) {
        synchronized (this) {
            if (!initWriter()) {
                return;
            }
            if (message.length() > 4096) {
                message = message.substring(0, 256) + "... TRUNCATED!\n\n";
            }
            try {
                writer.write(format(
                        "*** %s - %s",
                        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S")
                                .format(new Date()),
                        message));
            } catch (IOException e) {
                log.error("Unable to write gRPC call log", e);
            }
        }
    }

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
            MethodDescriptor<ReqT, RespT> methodDescriptor,
            CallOptions callOptions, Channel channel) {
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
                channel.newCall(methodDescriptor, callOptions.withoutWaitForReady())) {

            private final long callId = callIdGenerator.getAndIncrement();

            @Override
            public void sendMessage(ReqT message) {
                if (enabled.get()) {
                    write(format(
                            "%s >> OUTBOUND >> [callId=%s]\n%s\n",
                            methodDescriptor.getFullMethodName(),
                            callId,
                            message.toString()));
                }
                super.sendMessage(message);
            }

            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {

                if (enabled.get()) {
                    write(format(
                            "%s STARTED [callId=%s]\n%s\n\n",
                            methodDescriptor.getFullMethodName(),
                            callId,
                            headers.toString()));
                }

                Listener<RespT> listener = new ForwardingClientCallListener<RespT>() {
                    @Override
                    protected Listener<RespT> delegate() {
                        return responseListener;
                    }

                    @Override
                    public void onMessage(RespT message) {
                        if (enabled.get()) {
                            write(format(
                                    "%s << INBOUND << [callId=%s]\n%s\n",
                                    methodDescriptor.getFullMethodName(),
                                    callId,
                                    message.toString()));
                        }
                        super.onMessage(message);
                    }

                    @Override
                    public void onClose(Status status, Metadata trailers) {
                        if (enabled.get()) {
                            write(format(
                                    "%s CLOSED [callId=%s]\n%s\n%s\n\n",
                                    methodDescriptor.getFullMethodName(),
                                    callId,
                                    status.toString(),
                                    parseTrailers(trailers)));
                        }
                        super.onClose(status, trailers);
                    }

                    private String parseTrailers(Metadata trailers) {
                        StringJoiner joiner = new StringJoiner("\n");
                        joiner.add(trailers.toString());
                        // If Google's RPC Status trailers are found, parse them.
                        final Iterable<com.google.rpc.Status> statuses = trailers.getAll(
                                GRPC_STATUS_KEY);
                        if (statuses == null) {
                            return joiner.toString();
                        }
                        statuses.forEach(s -> joiner.add(s.toString()));
                        return joiner.toString();
                    }

                    @Override
                    public void onHeaders(Metadata headers) {
                        super.onHeaders(headers);
                    }
                };

                super.start(listener, headers);
            }
        };
    }
}
