﻿#region Copyright notice and license
// Copyright 2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Grpc.Core;
using Grpc.Reflection;
using Grpc.Reflection.V1Alpha;
using NUnit.Framework;

namespace Grpc.Reflection.Tests
{
    /// <summary>
    /// Reflection client talks to reflection server.
    /// </summary>
    public class ReflectionClientServerTest
    {
        const string Host = "localhost";
        Server server;
        Channel channel;
        ServerReflection.ServerReflectionClient client;
        ReflectionServiceImpl serviceImpl;

        [TestFixtureSetUp]
        public void Init()
        {
            serviceImpl = new ReflectionServiceImpl(ServerReflection.Descriptor);

            server = new Server
            {
                Services = { ServerReflection.BindService(serviceImpl) },
                Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } }
            };
            server.Start();
            channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure);

            client = new ServerReflection.ServerReflectionClient(channel);
        }

        [TestFixtureTearDown]
        public void Cleanup()
        {
            channel.ShutdownAsync().Wait();
            server.ShutdownAsync().Wait();
        }

        [Test]
        public async Task FileByFilename_NotFound()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                FileByFilename = "somepackage/nonexistent.proto"
            });
            Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode);
        }

        [Test]
        public async Task FileByFilename()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                FileByFilename = "grpc/reflection/v1alpha/reflection.proto"
            });
            Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count);
            Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]);
        }

        [Test]
        public async Task FileContainingSymbol()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                FileContainingSymbol = "grpc.reflection.v1alpha.ServerReflection"
            });
            Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count);
            Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]);
        }

        [Test]
        public async Task FileContainingSymbol_NotFound()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                FileContainingSymbol = "somepackage.Nonexistent"
            });
            Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode);
        }

        [Test]
        public async Task ListServices()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                ListServices = ""
            });
            Assert.AreEqual(1, response.ListServicesResponse.Service.Count);
            Assert.AreEqual(ServerReflection.Descriptor.FullName, response.ListServicesResponse.Service[0].Name);
        }

        [Test]
        public async Task FileContainingExtension()
        {
            var response = await SingleRequestAsync(new ServerReflectionRequest
            {
                FileContainingExtension = new ExtensionRequest()
            });
            Assert.AreEqual((int)StatusCode.Unimplemented, response.ErrorResponse.ErrorCode);
        }

        private async Task<ServerReflectionResponse> SingleRequestAsync(ServerReflectionRequest request)
        {
            var call = client.ServerReflectionInfo();
            await call.RequestStream.WriteAsync(request);
            Assert.IsTrue(await call.ResponseStream.MoveNext());

            var response = call.ResponseStream.Current;
            await call.RequestStream.CompleteAsync();
            Assert.IsFalse(await call.ResponseStream.MoveNext());
            return response;
        }
    }
}
