﻿// 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.Collections.Generic;
using Newtonsoft.Json;
using Org.Apache.REEF.Tang.Annotations;
using Org.Apache.REEF.Utilities.Attributes;
using Org.Apache.REEF.Utilities.Logging;

namespace Org.Apache.REEF.Common.Telemetry
{
    [Unstable("0.16", "This is to build a collection of counters for evaluator metrics.")]
    internal sealed class Counters : ICounters
    {
        private static readonly Logger Logger = Logger.GetLogger(typeof(Counters));

        /// <summary>
        /// It contains name and count pairs
        /// </summary>
        private readonly IDictionary<string, ICounter> _counters = new Dictionary<string, ICounter>();

        /// <summary>
        /// The lock for counters
        /// </summary>
        private readonly object _counterLock = new object();

        [Inject]
        private Counters()
        {
        }

        /// <summary>
        /// Deserialize a counters serialized string into a Counters object
        /// </summary>
        /// <param name="serializedCountersString"></param>
        internal Counters(string serializedCountersString)
        {
            var c = JsonConvert.DeserializeObject<IEnumerable<Counter>>(serializedCountersString);
            foreach (var ct in c)
            {
                _counters.Add(ct.Name, ct);
            }
        }

        public IEnumerable<ICounter> GetCounters()
        {
            return _counters.Values;
        }

        /// <summary>
        /// Register a new counter with a specified name.
        /// If name does not exist, the counter will be added and true will be returned
        /// Otherwise the counter will be not added and false will be returned. 
        /// </summary>
        /// <param name="name">Counter name</param>
        /// <param name="description">Counter description</param>
        /// <returns>Returns a boolean to indicate if the counter is added.</returns>
        public bool TryRegisterCounter(string name, string description)
        {
            lock (_counterLock)
            {
                if (_counters.ContainsKey(name))
                {
                    Logger.Log(Level.Warning, "The counter [{0}] already exists.", name);
                    return false;
                }
                _counters.Add(name, new Counter(name, description));
            }
            return true;
        }

        /// <summary>
        /// Get counter for a given name
        /// return false if the counter doesn't exist
        /// </summary>
        /// <param name="name">Name of the counter</param>
        /// <param name="value">Value of the counter returned</param>
        /// <returns>Returns a boolean to indicate if the value is found.</returns>
        public bool TryGetValue(string name, out ICounter value)
        {
            lock (_counterLock)
            {
                return _counters.TryGetValue(name, out value);
            }
        }

        /// <summary>
        /// Increase the counter with the given number
        /// </summary>
        /// <param name="name">Name of the counter</param>
        /// <param name="number">number to increase</param>
        public void Increment(string name, int number)
        {
            ICounter counter;
            if (TryGetValue(name, out counter))
            {
                lock (_counterLock)
                {
                    counter.Increment(number);
                }
            }
            else
            {
                Logger.Log(Level.Error, "The counter [{0}]  has not registered.", name);
                throw new ApplicationException("Counter has not registered:" + name);
            }
        }

        /// <summary>
        /// return serialized string of counter data
        /// TODO: [REEF-] use an unique number for the counter name mapping to reduce the data transfer over the wire
        /// TODO: [REEF-] use Avro schema if that can make the serialized string more compact
        /// </summary>
        /// <returns>Returns serialized string of the counters.</returns>
        public string Serialize()
        {
            lock (_counterLock)
            {
                if (_counters.Count > 0)
                {
                    return JsonConvert.SerializeObject(_counters.Values);
                }
                return null;
            }
        }
    }
}
