/*
 * 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.tinkerpop.gremlin.driver.ser;

import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy;

/**
 * An enum of the default serializers.
 *
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
public enum Serializers {
    /**
     * GraphSON 3.0.
     */
    GRAPHSON(SerTokens.MIME_JSON),
    GRAPHSON_V1D0(SerTokens.MIME_GRAPHSON_V1D0),
    GRAPHSON_V2D0(SerTokens.MIME_GRAPHSON_V2D0),
    GRAPHSON_V3D0(SerTokens.MIME_GRAPHSON_V3D0),
    GRAPHBINARY_V1D0(SerTokens.MIME_GRAPHBINARY_V1D0),

    /**
     * @deprecated As of release 3.4.3, replaced by {@link #GRAPHBINARY_V1D0}.
     */
    @Deprecated
    GRYO_V1D0(SerTokens.MIME_GRYO_V1D0),

    /**
     * @deprecated As of release 3.4.3, replaced by {@link #GRAPHBINARY_V1D0}.
     */
    @Deprecated
    GRYO_V3D0(SerTokens.MIME_GRYO_V3D0),

    /**
     * @deprecated As of release 3.2.6, not directly replaced - supported through {@link HaltedTraverserStrategy}.
     */
    @Deprecated
    GRYO_LITE_V1D0(SerTokens.MIME_GRYO_LITE_V1D0);

    private String value;

    Serializers(final String mimeType) {
        this.value = mimeType;
    }

    public String getValue() {
        return value;
    }

    public MessageSerializer simpleInstance() {
        switch (value) {
            case SerTokens.MIME_JSON:
                return new GraphSONMessageSerializerV3d0();
            case SerTokens.MIME_GRAPHSON_V1D0:
                return new GraphSONMessageSerializerGremlinV1d0();
            case SerTokens.MIME_GRAPHSON_V2D0:
                return new GraphSONMessageSerializerV2d0();
            case SerTokens.MIME_GRAPHSON_V3D0:
                return new GraphSONMessageSerializerV3d0();
            case SerTokens.MIME_GRYO_V1D0:
                return new GryoMessageSerializerV1d0();
            case SerTokens.MIME_GRYO_V3D0:
                return new GryoMessageSerializerV3d0();
            case SerTokens.MIME_GRYO_LITE_V1D0:
                return new GryoLiteMessageSerializerV1d0();
            case SerTokens.MIME_GRAPHBINARY_V1D0:
                return new GraphBinaryMessageSerializerV1();
            default:
                throw new RuntimeException("Could not create a simple MessageSerializer instance of " + value);
        }
    }
}
