/*
 * 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 Apache.NMS;
using Apache.NMS.Util;

namespace Apache.NMS.Stomp
{
    /// <summary>
    /// Class used to define the various limits that should be used for the Prefetch
    /// limit on destination based on the type of Destination in use.
    /// </summary>
    public class PrefetchPolicy : ICloneable
    {
        public const int MAX_PREFETCH_SIZE = Int16.MaxValue - 1;
        public const int DEFAULT_QUEUE_PREFETCH = 1000;
        public const int DEFAULT_QUEUE_BROWSER_PREFETCH = 500;
        public const int DEFAULT_DURABLE_TOPIC_PREFETCH = 100;
        public const int DEFAULT_TOPIC_PREFETCH = MAX_PREFETCH_SIZE;

        private int queuePrefetch;
        private int queueBrowserPrefetch;
        private int topicPrefetch;
        private int durableTopicPrefetch;
        private int maximumPendingMessageLimit;

        public PrefetchPolicy()
        {
            this.queuePrefetch = DEFAULT_QUEUE_PREFETCH;
            this.queueBrowserPrefetch = DEFAULT_QUEUE_BROWSER_PREFETCH;
            this.topicPrefetch = DEFAULT_TOPIC_PREFETCH;
            this.durableTopicPrefetch = DEFAULT_DURABLE_TOPIC_PREFETCH;
        }

        public int QueuePrefetch
        {
            get { return this.queuePrefetch; }
            set { this.queuePrefetch = RestrictToMaximum(value); }
        }

        public int QueueBrowserPrefetch
        {
            get { return this.queueBrowserPrefetch; }
            set { this.queueBrowserPrefetch = RestrictToMaximum(value); }
        }

        public int TopicPrefetch
        {
            get { return this.topicPrefetch; }
            set { this.topicPrefetch = RestrictToMaximum(value); }
        }

        public int DurableTopicPrefetch
        {
            get { return this.durableTopicPrefetch; }
            set { this.durableTopicPrefetch = RestrictToMaximum(value); }
        }

        public int MaximumPendingMessageLimit
        {
            get { return this.maximumPendingMessageLimit; }
            set { this.maximumPendingMessageLimit = value; }
        }

        public void SetAll(int value)
        {
            this.queuePrefetch = value;
            this.queueBrowserPrefetch = value;
            this.topicPrefetch = value;
            this.durableTopicPrefetch = value;
        }

        private int RestrictToMaximum(int value)
        {
            return System.Math.Min(value, MAX_PREFETCH_SIZE);
        }

        public Object Clone()
        {
            return this.MemberwiseClone();
        }
    }
}
