using Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

#if NET35
using systemAlias = global::KRPC.Client.Compatibility;
using genericCollectionsAlias = global::KRPC.Client.Compatibility;
#else
using systemAlias = global::System;
using genericCollectionsAlias = global::System.Collections.Generic;
#endif

// Generated code references its own deprecated members (e.g. when registering
// exception types), so suppress the deprecation warnings within this file.
#pragma warning disable 612, 618

namespace KRPC.Client.Services.ServiceA
{
    /// <summary>
    /// Extension methods for ServiceA service.
    /// </summary>
    public static class ExtensionMethods
    {
        /// <summary>
        /// Create an instance of the ServiceA service.
        /// </summary>
        public static global::KRPC.Client.Services.ServiceA.Service ServiceA (this global::KRPC.Client.IConnection connection)
        {
            return new global::KRPC.Client.Services.ServiceA.Service (connection);
        }
    }

    // The types the stubs encode and decode values of, built once each. A spec names the
    // positions inside a value that can hold null, which a C# type cannot always say.
    static class TypeSpecs
    {
        internal static readonly global::KRPC.Client.TypeSpec Spec0 = global::KRPC.Client.TypeSpec.For (typeof(global::KRPC.Client.Services.ServiceB.Mode));
        internal static readonly global::KRPC.Client.TypeSpec Spec1 = global::KRPC.Client.TypeSpec.For (typeof(global::System.Collections.Generic.IList<global::KRPC.Client.Services.ServiceB.Mode>));

        // The procedures whose values a C# type cannot describe on its own, which a call
        // built from an expression looks up by name
        static readonly global::System.Collections.Generic.Dictionary<string, global::KRPC.Client.TypeSpec> returnSpecs =
            new global::System.Collections.Generic.Dictionary<string, global::KRPC.Client.TypeSpec> {
            };

        static readonly global::System.Collections.Generic.Dictionary<string, global::KRPC.Client.TypeSpec[]> parameterSpecs =
            new global::System.Collections.Generic.Dictionary<string, global::KRPC.Client.TypeSpec[]> {
            };

        public static global::KRPC.Client.TypeSpec ReturnSpec (string procedure)
        {
            global::KRPC.Client.TypeSpec spec;
            return returnSpecs.TryGetValue (procedure, out spec) ? spec : null;
        }

        public static global::KRPC.Client.TypeSpec[] ParameterSpecs (string procedure)
        {
            global::KRPC.Client.TypeSpec[] specs;
            return parameterSpecs.TryGetValue (procedure, out specs) ? specs : null;
        }
    }

    /// <summary>
    /// ServiceA service.
    /// </summary>
    public class Service
    {
        global::KRPC.Client.IConnection connection;

        internal Service (global::KRPC.Client.IConnection serverConnection)
        {
            connection = serverConnection;
        }

        /// <summary>
        /// Defaults to a member of another service's enumeration.
        /// </summary>
        [global::KRPC.Client.Attributes.RPCAttribute ("ServiceA", "Frob", typeof(TypeSpecs))]
        public void Frob (global::KRPC.Client.Services.ServiceB.Mode mode = global::KRPC.Client.Services.ServiceB.Mode.Fast)
        {
            var _args = new ByteString[] {
                global::KRPC.Client.Encoder.Encode (mode, TypeSpecs.Spec0)
            };
            connection.Invoke ("ServiceA", "Frob", _args);
        }

        /// <summary>
        /// Defaults to a collection containing a member of another service's enumeration.
        /// </summary>
        [global::KRPC.Client.Attributes.RPCAttribute ("ServiceA", "FrobAll", typeof(TypeSpecs))]
        public void FrobAll (global::System.Collections.Generic.IList<global::KRPC.Client.Services.ServiceB.Mode> modes = null)
        {
            var _args = new ByteString[] {
                global::KRPC.Client.Encoder.Encode (modes ?? new global::System.Collections.Generic.List<global::KRPC.Client.Services.ServiceB.Mode> { global::KRPC.Client.Services.ServiceB.Mode.Fast }, TypeSpecs.Spec1)
            };
            connection.Invoke ("ServiceA", "FrobAll", _args);
        }
    }
}
