using LicenseSpring;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ManagementConsoleSample
{
    static class Program
    {
        public static void Main( string[] args )
        {
            try
            {
                ManagementSample managementSample = new ManagementSample();

                Console.WriteLine("List customers:");
                managementSample.ListCustomers();

                Console.WriteLine("List products:");
                managementSample.ListProducts();

                uint licenseCount = managementSample.ListLicensesCount();
                Console.WriteLine($"\nNumber of licenses: {licenseCount}\n");

                Console.WriteLine("Ordering key based licenses:");
                string keyBasedOrderId = managementSample.OrderKeyBasedLicenses();

                Console.WriteLine("Licenses of the order:");
                License[] licenses = managementSample.GetOrderLicenses(keyBasedOrderId);
                foreach (License license in licenses)
                {
                    PrintLicense(license);
                }

                string licenseKey = licenses[0].LicenseKey;
                Console.WriteLine("Creating an update file by license key: " + licenseKey);
                managementSample.CreateUpdateFileByKey(licenseKey);

                Console.WriteLine( "Ordering user based license:" );
                string userBasedOrderId = managementSample.OrderUserBasedLicense();
                License userBasedLicense = managementSample.GetOrderLicenses( userBasedOrderId )[0];
                PrintLicense( userBasedLicense );

                Console.WriteLine( "Assinging a user to the license:" );
                LicenseUser user = managementSample.AssignUserToLicense( userBasedLicense );

                Console.WriteLine( "Updating the user info:" );
                managementSample.EditLicenseUser( user );

                Console.WriteLine( "Updating the license:" );
                managementSample.UpdateLicense( userBasedLicense );

                Console.WriteLine( "Creating a license custom field:" );
                managementSample.CreateCustomField( userBasedLicense );
                
                PrintLicense( managementSample.GetLicenseById( userBasedLicense.Id ) );
                License licenseFromServer = managementSample.GetLicenseByKey( "enter some key" );
                PrintLicense( licenseFromServer );
                Device testDevice = managementSample.GetLicenseDevices( licenseFromServer )?[0];
                PrintDevice( testDevice );
                managementSample.UpdateDeviceVariables( testDevice );

                PrintPause();
            }
            catch( Exception ex )
            {
                PrintException( ex );
                PrintPause();
            }
        }

        public static void PrintException( Exception ex )
        {
            if( ex is LicenseSpringException )
                Console.WriteLine( "LicenseSpring exception encountered: " + ex.Message );
            else
                Console.WriteLine( "Exception encountered: " + ex.Message );

            Exception innerException = ex.InnerException;
            while( innerException != null )
            {
                Console.WriteLine( "Inner exception: " + innerException.Message );
                innerException = innerException.InnerException;
            }
            Console.WriteLine();
        }

        public static void PrintPause()
        {
            Console.WriteLine( "\nPlease press any key to continue..." );
            Console.ReadKey();
        }

        public static void PrintDevice( IDevice device )
        {
            if (device == null)
            {
                return;
            }

            Console.WriteLine( "------------- Device info -------------" );

            Console.WriteLine( "Hostname = {0}", device.Hostname );
            Console.WriteLine( "Type = {0}", device.Type );
            DeviceVariable[] dataFields = device.DeviceVariables;
            if( dataFields != null && dataFields.Count() > 0 )
            {
                Console.WriteLine( "Custom data fields available for this license:" );
                foreach( DeviceVariable field in dataFields )
                    Console.WriteLine( "Device variable - Name: {0}, Value: {1}", field.Variable, field.Value );
            }
        }

        public static void PrintLicense( ILicense license )
        {
            if( license == null )
                return;

            Console.WriteLine( "------------- License info -------------" );

            Customer owner = license.Owner;
            if( owner != null )
            {
                string ownerInfo = "";
                void formatInfo( string dataField )
                {
                    if( !string.IsNullOrEmpty( ownerInfo ) )
                        ownerInfo += " ";
                    if( !string.IsNullOrEmpty( dataField ) )
                        ownerInfo += dataField;
                }
                formatInfo( owner.FirstName );
                formatInfo( owner.LastName );
                formatInfo( owner.Email );
                formatInfo( owner.CompanyName );

                if( !string.IsNullOrEmpty( ownerInfo ) )
                    Console.WriteLine( "Licensed to: {0}", ownerInfo );
            }

            if( !string.IsNullOrEmpty( license.LicenseKey ) )
                Console.WriteLine( "Key = {0}", license.LicenseKey );

            if( license.LicenseUser != null )
                Console.WriteLine( "User = {0}", license.LicenseUser.Email );

            Console.WriteLine( "Type = {0}", license.LicenseType );
            Console.WriteLine( "Status = {0}", license.Status.ToString() );
            Console.WriteLine( "IsTrial = {0}", license.IsTrial );
            Console.WriteLine( "Times activated = {0}", license.TimesActivated );
            Console.WriteLine( "Max activations = {0}", license.MaxActivations );
            Console.WriteLine( "Validity Period = {0}", license.ValidityPeriodLocal() );
            Console.WriteLine( "Validity Period UTC = {0}", license.ValidityPeriod );
            Console.WriteLine( "Days remaining till license expires = {0}", license.DaysRemaining() );
            Console.WriteLine( "Maintenance period = {0}", license.MaintenancePeriodLocal() );
            Console.WriteLine( "Maintenance period UTC = {0}", license.MaintenancePeriod );
            Console.WriteLine( "Maintenance days remaining = {0}", license.MaintenanceDaysRemaining() );
            Console.WriteLine( "Is maintenance period expired = {0}", license.IsMaintenancePeriodExpired() );
            Console.WriteLine( "Note = {0}", license.Note );
            Console.WriteLine( "Metadata = {0}", license.Metadata );

            List<LicenseFeature> productFeatures = license.ProductFeatures;
            if( productFeatures != null && productFeatures.Count() > 0 )
            {
                Console.WriteLine( "Product features available for this license:" );
                foreach (LicenseFeature feature in productFeatures)
                {
                    Console.WriteLine( feature.ToString() );
                }
            }
            
            List<CustomField> dataFields = license.CustomFields;
            if( dataFields != null && dataFields.Count() > 0 )
            {
                Console.WriteLine( "Custom data fields available for this license:" );
                foreach( CustomField field in dataFields )
                    Console.WriteLine( "Data field - Name: {0}, Value: {1}", field.Name, field.Value );
            }

            if( license.LicenseType == LicenseType.Consumption )
            {
                Console.WriteLine( "Total consumption = {0}", license.TotalConsumptions );
                Console.WriteLine( "Max consumption = {0}", license.MaxConsumptions );
                Console.WriteLine( "Is consumption overage allowed = {0}", license.AllowOverages );
                if( license.AllowOverages )
                    Console.WriteLine( "Max consumption overage = {0}", license.MaxOverages );
            }

            if( license.IsFloating )
            {
                Console.WriteLine( "This license is floating" );
                Console.WriteLine( "Timeout = {0} min", license.FloatingTimeout );
                Console.WriteLine( "Floating users = {0}", license.FloatingUsers );
            }

            Console.WriteLine();
        }

    }
}
