﻿// 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.

using System;
using System.Threading.Tasks;
using Apache.Arrow.Flight.Internal;
using Apache.Arrow.Flight.Protocol;
using Grpc.Core;

namespace Apache.Arrow.Flight.Server.Internal
{
    /// <summary>
    /// This class has to be internal, since the generated code from proto is set as internal.
    /// </summary>
    internal class FlightServerImplementation : FlightService.FlightServiceBase
    {
        private readonly FlightServer _flightServer;
        public FlightServerImplementation(FlightServer flightServer)
        {
            _flightServer = flightServer;
        }

        public override async Task DoPut(IAsyncStreamReader<Protocol.FlightData> requestStream, IServerStreamWriter<Protocol.PutResult> responseStream, ServerCallContext context)
        {
            var readStream = new FlightServerRecordBatchStreamReader(requestStream);
            var writeStream = new StreamWriter<FlightPutResult, PutResult>(responseStream, putResult => putResult.ToProtocol());

            await _flightServer.DoPut(readStream, writeStream, context).ConfigureAwait(false);
        }

        public override Task DoGet(Protocol.Ticket request, IServerStreamWriter<Protocol.FlightData> responseStream, ServerCallContext context)
        {
            var flightTicket = new FlightTicket(request.Ticket_);
            var flightServerRecordBatchStreamWriter = new FlightServerRecordBatchStreamWriter(responseStream);

            return _flightServer.DoGet(flightTicket, flightServerRecordBatchStreamWriter, context);
        }

        public override Task ListFlights(Protocol.Criteria request, IServerStreamWriter<Protocol.FlightInfo> responseStream, ServerCallContext context)
        {
            var writeStream = new StreamWriter<FlightInfo, Protocol.FlightInfo>(responseStream, flightInfo => flightInfo.ToProtocol());

            return _flightServer.ListFlights(new FlightCriteria(request), writeStream, context);
        }

        public override Task DoAction(Protocol.Action request, IServerStreamWriter<Protocol.Result> responseStream, ServerCallContext context)
        {
            var action = new FlightAction(request);
            var writeStream = new StreamWriter<FlightResult, Protocol.Result>(responseStream, result => result.ToProtocol());

            return _flightServer.DoAction(action, writeStream, context);
        }

        public override async Task<SchemaResult> GetSchema(Protocol.FlightDescriptor request, ServerCallContext context)
        {
            var flightDescriptor = new FlightDescriptor(request);
            var schema = await _flightServer.GetSchema(flightDescriptor, context).ConfigureAwait(false);

            return new SchemaResult()
            {
                Schema = SchemaWriter.SerializeSchema(schema)
            };
        }

        public override async Task<Protocol.FlightInfo> GetFlightInfo(Protocol.FlightDescriptor request, ServerCallContext context)
        {
            var flightDescriptor = new FlightDescriptor(request);
            FlightInfo flightInfo = await _flightServer.GetFlightInfo(flightDescriptor, context).ConfigureAwait(false);

            return flightInfo.ToProtocol();
        }

        public override Task DoExchange(IAsyncStreamReader<Protocol.FlightData> requestStream, IServerStreamWriter<Protocol.FlightData> responseStream, ServerCallContext context)
        {
            var readStream = new FlightServerRecordBatchStreamReader(requestStream);
            var writeStream = new FlightServerRecordBatchStreamWriter(responseStream);
            return _flightServer.DoExchange(readStream, writeStream, context);
        }

        public override Task Handshake(IAsyncStreamReader<HandshakeRequest> requestStream, IServerStreamWriter<HandshakeResponse> responseStream, ServerCallContext context)
        {
            var readStream = new StreamReader<HandshakeRequest, FlightHandshakeRequest>(requestStream, request => new FlightHandshakeRequest(request));
            var writeStream = new StreamWriter<FlightHandshakeResponse, Protocol.HandshakeResponse>(responseStream, result => result.ToProtocol());
            return _flightServer.Handshake(readStream, writeStream, context);
        }

        public override async Task ListActions(Empty request, IServerStreamWriter<Protocol.ActionType> responseStream, ServerCallContext context)
        {
            var writeStream = new StreamWriter<FlightActionType, Protocol.ActionType>(responseStream, (actionType) => actionType.ToProtocol());
            await _flightServer.ListActions(writeStream, context).ConfigureAwait(false);
        }
    }
}
