/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.dubbo.common.serialize.protobuf.support;

import com.google.protobuf.Any;
import com.google.protobuf.BoolValue;
import com.google.protobuf.ByteString;
import com.google.protobuf.DoubleValue;
import com.google.protobuf.Empty;
import com.google.protobuf.FloatValue;
import com.google.protobuf.Int32Value;
import com.google.protobuf.Int64Value;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.StringValue;

import org.apache.dubbo.common.serialize.protobuf.support.wrapper.MapValue;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * ProtobufAttachmentUtils
 */
public class ProtobufAttachmentUtils {
    private static Map<String, BuiltinMarshaller> marshallers = new HashMap<>();
    private final static String NULL_CLASS_NAME = "null";

    static {
        marshaller(String.class, new StringMarshaller());
        marshaller(Integer.class, new IntegerMarshaller());
        marshaller(Long.class, new LongMarshaller());
        marshaller(Boolean.class, new BooleanMarshaller());
        marshaller(Float.class, new FloatMarshaller());
        marshaller(Double.class, new DoubleMarshaller());
        marshallers.put(NULL_CLASS_NAME, new NullMarshaller());
    }

    static void marshaller(Class<?> clazz, BuiltinMarshaller marshaller) {
        marshallers.put(clazz.getCanonicalName(), marshaller);
    }

    static MapValue.Map wrap(Map<String, Object> attachments) throws IOException {
        Map<String, Any> genericAttachments = new HashMap<>(attachments.size());
        Map<String, String> stringAttachments = new HashMap<>(attachments.size());
        for (Map.Entry<String, Object> entry : attachments.entrySet()) {
            genericAttachments.put(entry.getKey(), marshal(entry.getValue()));
            stringAttachments.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        return MapValue.Map.newBuilder().putAllAttachmentsV2(genericAttachments).putAllAttachments(stringAttachments).build();
    }

    static Map<String, Object> unwrap(MapValue.Map map) throws InvalidProtocolBufferException {
        Map<String, Object> attachments = new HashMap<>();
        //compatible with older version.
        Map<String, String> stringAttachments = map.getAttachmentsMap();
        if (stringAttachments != null) {
            stringAttachments.forEach((k, v) -> attachments.put(k, v));
        }

        Map<String, Any> genericAttachments = map.getAttachmentsV2Map();
        if (genericAttachments == null) {
            return attachments;
        }
        for (Map.Entry<String, Any> entry : genericAttachments.entrySet()) {
            attachments.put(entry.getKey(), unmarshal(entry.getValue()));
        }
        return attachments;
    }

    private static Any marshal(Object obj) throws IOException {
        String className = NULL_CLASS_NAME;
        if (obj != null) {
            className = obj.getClass().getCanonicalName();
        }
        BuiltinMarshaller marshaller = marshallers.get(className);
        if (marshaller == null) {
            throw new IllegalStateException(className + " in attachment is not supported by protobuf.");
        }

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ProtobufUtils.serialize(StringValue.newBuilder().setValue(className).build(), stream);
        marshaller.marshal(obj, stream);
        stream.flush();
        return Any.newBuilder().setValue(ByteString.copyFrom(stream.toByteArray())).build();
    }

    private static Object unmarshal(Any any) throws InvalidProtocolBufferException {
        InputStream stream = new ByteArrayInputStream(any.getValue().toByteArray());
        String className = ProtobufUtils.deserialize(stream, StringValue.class).getValue();
        BuiltinMarshaller marshaller = marshallers.get(className);
        if (marshaller == null) {
            throw new IllegalStateException(className + " in attachment is not supported by protobuf.");
        }
        return marshaller.unmarshal(stream);
    }

    private static interface BuiltinMarshaller<T> {
        void marshal(T obj, OutputStream stream) throws IOException;

        T unmarshal(InputStream stream) throws InvalidProtocolBufferException;
    }

    static class StringMarshaller implements BuiltinMarshaller<String> {
        @Override
        public void marshal(String obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(StringValue.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public String unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, StringValue.class).getValue();
        }
    }

    static class IntegerMarshaller implements BuiltinMarshaller<Integer> {
        @Override
        public void marshal(Integer obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(Int32Value.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public Integer unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, Int32Value.class).getValue();
        }
    }

    static class LongMarshaller implements BuiltinMarshaller<Long> {
        @Override
        public void marshal(Long obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(Int64Value.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public Long unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, Int64Value.class).getValue();
        }
    }

    static class BooleanMarshaller implements BuiltinMarshaller<Boolean> {
        @Override
        public void marshal(Boolean obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(BoolValue.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public Boolean unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, BoolValue.class).getValue();
        }
    }

    static class FloatMarshaller implements BuiltinMarshaller<Float> {
        @Override
        public void marshal(Float obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(FloatValue.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public Float unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, FloatValue.class).getValue();
        }
    }

    static class DoubleMarshaller implements BuiltinMarshaller<Double> {
        @Override
        public void marshal(Double obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(DoubleValue.newBuilder().setValue(obj).build(), stream);
        }

        @Override
        public Double unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return ProtobufUtils.deserialize(stream, DoubleValue.class).getValue();
        }
    }

    static class NullMarshaller implements BuiltinMarshaller<Object> {

        @Override
        public void marshal(Object obj, OutputStream stream) throws IOException {
            ProtobufUtils.serialize(Empty.newBuilder().build(), stream);
        }

        @Override
        public Object unmarshal(InputStream stream) throws InvalidProtocolBufferException {
            return null;
        }
    }
}
