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

namespace UpdateLicenseOfflineSample
{
    static class Program
    {
        static void Main( string[] args )
        {
            try
            {
                var configuration = LSConfig.CreateManagementConfiguration();
                var service = new ManagementService( configuration );

                // Create customer and license
                Customer customer = new Customer()
                {
                    CompanyName = "TestCompany",
                    Email = "someone@test.com"
                };
                var license1 = new LicenseDetails
                {
                    Type = LicenseType.Consumption,
                    MaxConsumptions = 100,
                    AllowOverages = true,
                    MaxOverages = 50,
                    ResetConsumption = true,
                    ConsumptionPeriod = "week"
                };

                var licenses = new List<LicenseDetails>
                    {
                        license1
                    };
                string productCode = "UPS";//user-based
                var orderInfo = new Order( customer );
                // Order 1 license
                var orderID = service.OrderService.CreateOrder( licenses.ToArray(), productCode, orderInfo );

                ListLicensesRequestDto dto = new ListLicensesRequestDto()
                {
                    OrderStoreId = orderID
                };

                //Getting the licenses of the order
                var licensesOnOrder = new List<License>();
                int limit = 20;
                int offset = 0;
                uint count;

                do
                {
                    dto.Limit = limit;
                    dto.Offset = offset;

                    var range = service.LicenseService.ListLicenses( dto, out count );

                    if( range != null ) licensesOnOrder.AddRange( range );

                    offset += limit;

                } while( offset < count );

                //Creating another user
                LicenseUser user = new LicenseUser()
                {
                    Email = "someunrealmail@unmail.ua",
                    FirstName = "Unreal",
                    LastName = "Person",
                    Password = "qwerty12345"
                };

                if( licensesOnOrder[0] != null )
                {
                    PrintLicense( licensesOnOrder[0] );
                    //Assign the user to the license
                    //Existing user will be assigned, if there are no users with such email, a new user will be created
                    service.LicenseService.AssignUser( licensesOnOrder[0].Id, user );
                    dto.IdIn = licensesOnOrder[0].Id;

                    licensesOnOrder.Clear();
                    limit = 20;
                    offset = 0;
                    count = 0;
                    //Getting the licenses of the order
                    do
                    {
                        dto.Limit = limit;
                        dto.Offset = offset;

                        var range = service.LicenseService.ListLicenses( dto, out count );

                        if( range != null ) licensesOnOrder.AddRange( range );

                        offset += limit;

                    } while( offset < count );

                    PrintLicense( licensesOnOrder[0] );
                }
                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.ReadLine();
        }

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

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

            var 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 );
            if( license.LicenseUsers != null )
            {
                foreach( var user in license.LicenseUsers )
                    Console.WriteLine( "User = {0}", user.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() );

            var 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() );
            }

            var 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();
        }

    }
}
