/*
 * 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;

namespace Apache.NMS.AMQP
{
    public class NmsConsumer : INMSConsumer
    {
        
        private readonly ISession session;
        private readonly NmsMessageConsumer consumer;

        public NmsConsumer(ISession session, NmsMessageConsumer consumer) {
            this.session = session;
            this.consumer = consumer;
        }

        public void Dispose()
        {
            consumer.Dispose();
        }

        public IMessage Receive()
        {
            return consumer.Receive();
        }

        public Task<IMessage> ReceiveAsync()
        {
            return consumer.ReceiveAsync();
        }

        public IMessage Receive(TimeSpan timeout)
        {
            return consumer.Receive(timeout);
        }

        public Task<IMessage> ReceiveAsync(TimeSpan timeout)
        {
            return consumer.ReceiveAsync(timeout);
        }

        public IMessage ReceiveNoWait()
        {
            return consumer.ReceiveNoWait();
        }

        public T ReceiveBody<T>()
        {
            return consumer.ReceiveBody<T>();
        }

        public Task<T> ReceiveBodyAsync<T>()
        {
            return consumer.ReceiveBodyAsync<T>();
        }

        public T ReceiveBody<T>(TimeSpan timeout)
        {
            return consumer.ReceiveBody<T>(timeout);
        }

        public Task<T> ReceiveBodyAsync<T>(TimeSpan timeout)
        {
            return consumer.ReceiveBodyAsync<T>(timeout);
        }

        public T ReceiveBodyNoWait<T>()
        {
            return consumer.ReceiveBodyNoWait<T>();
        }

        public void Close()
        {
            consumer.Close();
        }

        public Task CloseAsync()
        {
            return consumer.CloseAsync();
        }

        public string MessageSelector => consumer.MessageSelector;

        public ConsumerTransformerDelegate ConsumerTransformer
        {
            get => consumer.ConsumerTransformer; 
            set => consumer.ConsumerTransformer = value; 
        }

        event MessageListener INMSConsumer.Listener
        {
            add => ((IMessageConsumer)consumer).Listener += value;
            remove => ((IMessageConsumer)consumer).Listener -= value;
        }
    }
}