/*
 *****************************************************************************
 *                                                                           *
 *              IMPINJ CONFIDENTIAL AND PROPRIETARY                          *
 *                                                                           *
 * This source code is the sole property of Impinj, Inc. Reproduction or     *
 * utilization of this source code in whole or in part is forbidden without  *
 * the prior written consent of Impinj, Inc.                                 *
 *                                                                           *
 * (c) Copyright Impinj, Inc. 2015. All rights reserved.                     *
 *                                                                           *
 *****************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Impinj.STP;

namespace Impinj
{
    class Utilities
    {
        /// <summary>
        /// Utility procedure for converting the ItemEncode device epoch
        /// timestamp with microsecond resolution to the standard
        /// .NET DateTime format.
        /// </summary>
        /// <param name="usecondsSinceEpoch">
        /// The usecondsSinceEpoch field from an ItemEncode/ItemVerify
        /// Timestamp object
        /// </param>
        /// <returns>
        /// A .NET DateTime object.
        /// </returns>
        public static DateTime GetDateTime(ulong? usecondsSinceEpoch)
        {
            DateTime retDateTime = DateTime.Now;

            try
            {
                if (true == usecondsSinceEpoch.HasValue)
                {
                    // Extract the Epoch baseline value
                    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
                    // Convert the provided microseconds to an Epoch value in ticks
                    long ticks = (long)usecondsSinceEpoch * 10 + epoch.Ticks;

                    // Create the return DateTime value
                    retDateTime = new DateTime(ticks, DateTimeKind.Utc);
                }
                else
                {
                    throw (new ArgumentException("NULL usecondTimestamp value"));
                }
            }
            catch
            {
                throw;
            }

            return retDateTime;
        }

        /// <summary>
        /// Utility procedure for converting an ItemEncode device Timestamp
        /// object into the standard .NET DateTime equivalent.
        /// </summary>
        /// <param name="usecondsSinceEpoch">
        /// An ItemEncode/ItemVerify Timestamp object
        /// </param>
        /// <returns>
        /// A .NET DateTime object.
        /// </returns>
        public static DateTime GetDateTime(Timestamp usecondTimestamp)
        {
            DateTime retDateTime = DateTime.Now;

            try
            {
                if (true == usecondTimestamp.UsecondsSinceEpoch.HasValue)
                {
                    // Extract the Epoch baseline value
                    DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
                    // Convert the provided microseconds data member from the
                    // provided timestamp to an Epoch value in ticks
                    long ticks =
                        (long)usecondTimestamp.UsecondsSinceEpoch.Value * 10 + epoch.Ticks;

                    // Create the return DateTime value
                    retDateTime = new DateTime(ticks, DateTimeKind.Utc);
                }
                else
                {
                    throw (new ArgumentException("NULL usecondTimestamp value"));
                }
            }
            catch
            {
                throw;
            }

            return retDateTime;
        }

        /// <summary>
        /// Utility procedure for printing out the details of an exception object
        /// </summary>
        /// <param name="exception">An exception object</param>
        public static void printExceptionDetails(Exception exception)
        {
            if (null != exception)
            {
                // Collate the exception details into a string
                string ex_msg = string.Format("{0}{1}",
                    exception.Message,
                    (null == exception.InnerException) ?
                    string.Empty :
                    Environment.NewLine + exception.InnerException.Message
                    );

                // Output the exception details
                Console.WriteLine("Exception: {0}", ex_msg);
                Console.WriteLine("{0}", exception.StackTrace.ToString());
            }
            else
            {
                Console.WriteLine("Exception: NULL");
            }
        }
    }
}
