﻿#region Copyright notice and license
// Protocol Buffers - Google's data interchange format
// Copyright 2017 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#endregion

using Google.Protobuf.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

namespace Google.Protobuf.Reflection
{
    /// <summary>
    /// Container for a set of custom options specified within a message, field etc.
    /// </summary>
    /// <remarks>
    /// <para>
    /// This type is publicly immutable, but internally mutable. It is only populated
    /// by the descriptor parsing code - by the time any user code is able to see an instance,
    /// it will be fully initialized.
    /// </para>
    /// <para>
    /// If an option is requested using the incorrect method, an answer may still be returned: all
    /// of the numeric types are represented internally using 64-bit integers, for example. It is up to
    /// the caller to ensure that they make the appropriate method call for the option they're interested in.
    /// Note that enum options are simply stored as integers, so the value should be fetched using
    /// <see cref="TryGetInt32(int, out int)"/> and then cast appropriately.
    /// </para>
    /// <para>
    /// Repeated options are currently not supported. Asking for a single value of an option
    /// which was actually repeated will return the last value, except for message types where
    /// all the set values are merged together.
    /// </para>
    /// </remarks>
    [DebuggerDisplay("Count = {DebugCount}")]
    [DebuggerTypeProxy(typeof(CustomOptionsDebugView))]
    public sealed class CustomOptions
    {
        private const string UnreferencedCodeMessage = "CustomOptions is incompatible with trimming.";

        private static readonly object[] EmptyParameters = new object[0];
        private readonly IDictionary<int, IExtensionValue> values;

        internal CustomOptions(IDictionary<int, IExtensionValue> values)
        {
            this.values = values;
        }

        /// <summary>
        /// Retrieves a Boolean value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetBool(int field, out bool value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a signed 32-bit integer value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetInt32(int field, out int value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a signed 64-bit integer value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetInt64(int field, out long value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves an unsigned 32-bit integer value for the specified option field,
        /// assuming a fixed-length representation.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetFixed32(int field, out uint value) => TryGetUInt32(field, out value);

        /// <summary>
        /// Retrieves an unsigned 64-bit integer value for the specified option field,
        /// assuming a fixed-length representation.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetFixed64(int field, out ulong value) => TryGetUInt64(field, out value);

        /// <summary>
        /// Retrieves a signed 32-bit integer value for the specified option field,
        /// assuming a fixed-length representation.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetSFixed32(int field, out int value) => TryGetInt32(field, out value);

        /// <summary>
        /// Retrieves a signed 64-bit integer value for the specified option field,
        /// assuming a fixed-length representation.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetSFixed64(int field, out long value) => TryGetInt64(field, out value);

        /// <summary>
        /// Retrieves a signed 32-bit integer value for the specified option field,
        /// assuming a zigzag encoding.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetSInt32(int field, out int value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a signed 64-bit integer value for the specified option field,
        /// assuming a zigzag encoding.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetSInt64(int field, out long value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves an unsigned 32-bit integer value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetUInt32(int field, out uint value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves an unsigned 64-bit integer value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetUInt64(int field, out ulong value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a 32-bit floating point value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetFloat(int field, out float value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a 64-bit floating point value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetDouble(int field, out double value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a string value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetString(int field, out string value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a bytes value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetBytes(int field, out ByteString value) => TryGetPrimitiveValue(field, out value);

        /// <summary>
        /// Retrieves a message value for the specified option field.
        /// </summary>
        /// <param name="field">The field to fetch the value for.</param>
        /// <param name="value">The output variable to populate.</param>
        /// <returns><c>true</c> if a suitable value for the field was found; <c>false</c> otherwise.</returns>
        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        public bool TryGetMessage<T>(int field, out T value) where T : class, IMessage, new()
        {
            if (values == null)
            {
                value = default;
                return false;
            }

            if (values.TryGetValue(field, out IExtensionValue extensionValue))
            {
                if (extensionValue is ExtensionValue<T> single)
                {
                    ByteString bytes = single.GetValue().ToByteString();
                    value = new T();
                    value.MergeFrom(bytes);
                    return true;
                }
                else if (extensionValue is RepeatedExtensionValue<T> repeated)
                {
                    value = repeated.GetValue()
                        .Select(v => v.ToByteString())
                        .Aggregate(new T(), (t, b) =>
                        {
                            t.MergeFrom(b);
                            return t;
                        });
                    return true;
                }
            }

            value = null;
            return false;
        }

        [RequiresUnreferencedCode(UnreferencedCodeMessage)]
        private bool TryGetPrimitiveValue<T>(int field, out T value)
        {
            if (values == null)
            {
                value = default;
                return false;
            }

            if (values.TryGetValue(field, out IExtensionValue extensionValue))
            {
                if (extensionValue is ExtensionValue<T> single)
                {
                    value = single.GetValue();
                    return true;
                }
                else if (extensionValue is RepeatedExtensionValue<T> repeated)
                {
                    if (repeated.GetValue().Count != 0)
                    {
                        RepeatedField<T> repeatedField = repeated.GetValue();
                        value = repeatedField[repeatedField.Count - 1];
                        return true;
                    }
                }
                else // and here we find explicit enum handling since T : Enum ! x is ExtensionValue<Enum>
                {
                    var type = extensionValue.GetType();
                    if (type.GetGenericTypeDefinition() == typeof(ExtensionValue<>))
                    {
                        var typeInfo = type.GetTypeInfo();
                        var typeArgs = typeInfo.GenericTypeArguments;
                        if (typeArgs.Length == 1 && typeArgs[0].GetTypeInfo().IsEnum)
                        {
                            value = (T)typeInfo.GetDeclaredMethod(nameof(ExtensionValue<T>.GetValue)).Invoke(extensionValue, EmptyParameters);
                            return true;
                        }
                    }
                    else if (type.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>))
                    {
                        var typeInfo = type.GetTypeInfo();
                        var typeArgs = typeInfo.GenericTypeArguments;
                        if (typeArgs.Length == 1 && typeArgs[0].GetTypeInfo().IsEnum)
                        {
                            var values = (IList)typeInfo.GetDeclaredMethod(nameof(RepeatedExtensionValue<T>.GetValue)).Invoke(extensionValue, EmptyParameters);
                            if (values.Count != 0)
                            {
                                value = (T)values[values.Count - 1];
                                return true;
                            }
                        }
                    }
                }
            }

            value = default;
            return false;
        }

        private int DebugCount => values?.Count ?? 0;

        private sealed class CustomOptionsDebugView
        {
            private readonly CustomOptions customOptions;

            public CustomOptionsDebugView(CustomOptions customOptions)
            {
                this.customOptions = customOptions;
            }

            [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
            public KeyValuePair<int, IExtensionValue>[] Items => customOptions.values?.ToArray() ?? new KeyValuePair<int, IExtensionValue>[0];
        }
    }
}
