text:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using HETSAPI.Models;
using HETSAPI.ViewModels;
using HETSAPI.Mappings;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace HETSAPI.Services.Impl
{
    /// <summary>
    /// Equipment Status Class - required to update the status record only
    /// </summary>
    public class EquipmentStatus
    {
        public string Status { get; set; }
        public string StatusComment { get; set; }
    }

    /// <summary>
    /// Equipment Rental Agreement Clone Class - required to clone a previous agreement
    /// </summary>
    public class EquipmentRentalAgreementClone
    {
        public int EquipmentId { get; set; }
        public int AgreementToCloneId { get; set; }
        public int RentalAgreementId { get; set; }
    }

    /// <summary>
    /// Equipment Service
    /// </summary>
    public class EquipmentService : ServiceBase, IEquipmentService
    {
        private readonly DbAppContext _context;
        private readonly IConfiguration _configuration;
        private readonly ILogger _logger;

        /// <summary>
        /// Equipment Service Constructor
        /// </summary>
        public EquipmentService(IHttpContextAccessor httpContextAccessor, DbAppContext context, IConfiguration configuration, ILoggerFactory loggerFactory)
            : base(httpContextAccessor, context)
        {
            _context = context;
            _configuration = configuration;
            _logger = loggerFactory.CreateLogger<EquipmentService>();
        }

        /// <summary>
        /// Create bulk equipment records
        /// </summary>
        /// <param name="items"></param>
        /// <response code="201">Equipment created</response>
        public virtual IActionResult EquipmentBulkPostAsync(Equipment[] items)
        {
            if (items == null)
            {
                return new BadRequestResult();
            }

            foreach (Equipment item in items)
            {
                AdjustRecord(item);

                // determine if this is an insert or an update
                bool exists = _context.Equipments.Any(a => a.Id == item.Id);

                if (exists)
                {
                    _context.Update(item);
                }
                else
                {
                    _context.Add(item);
                }
            }

            // save the changes
            _context.SaveChanges();

            return new NoContentResult();
        }

        /// <summary>
        /// Get equipment record
        /// </summary>
        /// <param name="id">id of Equipment to fetch</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdGetAsync(int id)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                Equipment result = _context.Equipments.AsNoTracking()
                    .Include(x => x.LocalArea.ServiceArea.District.Region)
                    .Include(x => x.DistrictEquipmentType)
                        .ThenInclude(d => d.EquipmentType)
                    .Include(x => x.Owner)
                    .Include(x => x.EquipmentAttachments)
                    .Include(x => x.Notes)
                    .Include(x => x.Attachments)
                    .Include(x => x.History)
                    .First(a => a.Id == id);

                result.IsHired = IsHired(id);
                result.NumberOfBlocks = GetNumberOfBlocks(result);
                result.HoursYtd = result.GetYtdServiceHours(_context);

                return new ObjectResult(new HetsResponse(result));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        // add an "IsHired" flag to indicate if this equipment is currently in use
        private bool IsHired(int id)
        {
            // add an "IsHired" flag to indicate if this equipment is currently in use
            IQueryable<RentalAgreement> agreements = _context.RentalAgreements.AsNoTracking()
                .Include(x => x.Equipment)
                .Where(x => x.Status == "Active");

            if (agreements.Any(x => x.Equipment.Id == id))
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Update equipment record
        /// </summary>
        /// <param name="id">id of Equipment to update</param>
        /// <param name="item"></param>
        /// <response code="200">OK</response>
        /// <response code="404">Equipment not found</response>
        public virtual IActionResult EquipmentIdPutAsync(int id, Equipment item)
        {
            if (item != null)
            {
                AdjustRecord(item);

                DateTime? originalSeniorityEffectiveDate = _context.GetEquipmentSeniorityEffectiveDate(id);

                bool exists = _context.Equipments.Any(a => a.Id == id);

                // check for duplicates (serial number)
                if (exists &&
                    id == item.Id &&
                    !string.IsNullOrEmpty(item.SerialNumber))
                {
                    bool duplicatesExist = _context.Equipments.Any(x => x.SerialNumber == item.SerialNumber &&
                                                                        x.Id != item.Id &&
                                                                        x.ArchiveCode == "N");
                    if (duplicatesExist)
                    {
                        // duplicate equipment error
                        return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-08", _configuration)));
                    }
                }

                if (exists && id == item.Id)
                {
                    _context.Equipments.Update(item);

                    // save the changes
                    _context.SaveChanges();

                    // if seniority has changed, update blocks
                    if ((originalSeniorityEffectiveDate == null && item.SeniorityEffectiveDate != null) ||
                        (originalSeniorityEffectiveDate != null && item.SeniorityEffectiveDate != null
                            && originalSeniorityEffectiveDate < item.SeniorityEffectiveDate))
                    {
                        EquipmentRecalcSeniority(item.LocalArea.Id, item.DistrictEquipmentType.Id, _context, _configuration);
                    }

                    // retrieve updated equipment record to return to ui
                    Equipment result = _context.Equipments.AsNoTracking()
                        .Include(x => x.LocalArea.ServiceArea.District.Region)
                        .Include(x => x.DistrictEquipmentType)
                            .ThenInclude(d => d.EquipmentType)
                        .Include(x => x.Owner)
                        .Include(x => x.EquipmentAttachments)
                        .Include(x => x.Notes)
                        .Include(x => x.Attachments)
                        .Include(x => x.History)
                        .First(a => a.Id == id);

                    result.IsHired = IsHired(id);
                    result.NumberOfBlocks = GetNumberOfBlocks(result);
                    result.HoursYtd = result.GetYtdServiceHours(_context);

                    return new ObjectResult(new HetsResponse(result));
                }

                // record not found
                return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Update equipment status
        /// </summary>
        /// <param name="id">id of Equipment to update</param>
        /// <param name="item"></param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdStatusPutAsync(int id, EquipmentStatus item)
        {
            bool recalcSeniority = false;

            if (item != null)
            {
                bool exists = _context.Equipments.Any(a => a.Id == id);

                if (exists)
                {
                    Equipment equipment = _context.Equipments
                        .Include(x => x.LocalArea.ServiceArea.District.Region)
                        .Include(x => x.DistrictEquipmentType)
                            .ThenInclude(d => d.EquipmentType)
                        .Include(x => x.Owner)
                        .Include(x => x.EquipmentAttachments)
                        .First(a => a.Id == id);

                    // used for seniority recalc
                    int localAreaId = equipment.LocalArea.Id;
                    int districtEquipmentTypeId = equipment.DistrictEquipmentType.Id;
                    string oldStatus = equipment.Status;

                    // update equipment status
                    equipment.Status = item.Status;
                    equipment.StatusComment = item.StatusComment;

                    if (equipment.Status.Equals("Archived", StringComparison.CurrentCultureIgnoreCase))
                    {
                        equipment.ArchiveCode = "Y";
                        equipment.ArchiveDate = DateTime.UtcNow;
                        equipment.ArchiveReason = "Equipment Archived";

                        // recalc seniority (move out of the block and adjust)
                        recalcSeniority = true;
                    }
                    else
                    {
                        equipment.ArchiveCode = "N";
                        equipment.ArchiveDate = null;
                        equipment.ArchiveReason = null;

                        // make sure the seniority is set when shifting to "Active" state
                        // (if this was a new record with no block/seniority yet)
                        if (equipment.BlockNumber == null &&
                            equipment.Seniority == null &&
                            equipment.Status.Equals("Approved", StringComparison.CurrentCultureIgnoreCase))
                        {
                            // per HETS-536 -> ignore and let the user set the "Approved Date" date

                            // recalc seniority (move into a block)
                            recalcSeniority = true;
                        }
                        else if ((oldStatus.Equals("Approved", StringComparison.CurrentCultureIgnoreCase) &&
                                  !equipment.Status.Equals("Approved", StringComparison.CurrentCultureIgnoreCase)) ||
                                 (!oldStatus.Equals("Approved", StringComparison.CurrentCultureIgnoreCase) &&
                                  equipment.Status.Equals("Approved", StringComparison.CurrentCultureIgnoreCase)))
                        {
                            // recalc seniority (move into or out of a block)
                            recalcSeniority = true;
                        }
                    }

                    // save the changes
                    _context.SaveChanges();

                    // recalc seniority (if required)
                    if (recalcSeniority)
                    {
                        EquipmentRecalcSeniority(localAreaId, districtEquipmentTypeId, _context, _configuration);
                    }

                    equipment.IsHired = IsHired(id);

                    return new ObjectResult(new HetsResponse(equipment));
                }

                // record not found
                return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Create equipment record
        /// </summary>
        /// <param name="item"></param>
        /// <response code="201">Equipment created</response>
        public virtual IActionResult EquipmentPostAsync(Equipment item)
        {
            if (item != null)
            {
                AdjustRecord(item);

                bool exists = _context.Equipments.Any(a => a.Id == item.Id);

                // check for duplicates (serial number)
                if (exists &&
                    !string.IsNullOrEmpty(item.SerialNumber))
                {
                    bool duplicatesExist = _context.Equipments.Any(x => x.SerialNumber == item.SerialNumber &&
                                                                        x.Id != item.Id &&
                                                                        x.ArchiveCode == "N");
                    if (duplicatesExist)
                    {
                        // duplicate equipment error
                        return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-08", _configuration)));
                    }
                }

                if (exists)
                {
                    _context.Equipments.Update(item);
                    _context.SaveChanges();
                }
                else
                {
                    // ***********************************************************************************
                    // Set default values for new piece of Equipment
                    // certain fields are set on new record - set defaults (including status = "Inactive")
                    // ***********************************************************************************
                    SetNewRecordFields(item);

                    // ***********************************************************************************
                    // Calculate Years of Service for new record
                    // ***********************************************************************************
                    // Business Rules:
                    // 1. When the equipment is added the years registered is set to a fraction of the
                    //    fiscal left from the registered date to the end of current fiscal
                    //    (decimals: 3 places)
                    // 2. On roll over the years registered increments by one for each year the equipment
                    //    stays active ((might need use the TO_DATE field to track when last it was rolled over)
                    //    TO_DATE = END OF CURRENT FISCAL

                    // determine end of current fscal year
                    DateTime fiscalEnd;

                    if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3)
                    {
                        fiscalEnd = new DateTime(DateTime.UtcNow.Year, 3, 31);
                    }
                    else
                    {
                        fiscalEnd = new DateTime(DateTime.UtcNow.AddYears(1).Year, 3, 31);
                    }

                    // is this a leap year?
                    if (DateTime.IsLeapYear(fiscalEnd.Year))
                    {
                        item.YearsOfService = (float) Math.Round((fiscalEnd - DateTime.UtcNow).TotalDays / 366, 3);
                    }
                    else
                    {
                        item.YearsOfService = (float)Math.Round((fiscalEnd - DateTime.UtcNow).TotalDays / 365, 3);
                    }

                    item.ToDate = fiscalEnd;

                    // ***********************************************************************************
                    // Save record
                    // ***********************************************************************************
                    _context.Equipments.Add(item);
                    _context.SaveChanges();

                    // add the equipment to the Owner's equipment list
                    Owner owner = item.Owner;

                    if (owner != null)
                    {
                        if (owner.EquipmentList == null)
                        {
                            owner.EquipmentList = new List<Equipment>();
                        }

                        if (!owner.EquipmentList.Contains(item))
                        {
                            owner.EquipmentList.Add(item);
                            _context.Owners.Update(owner);
                        }
                    }

                    // save changes
                    _context.SaveChanges();
                }

                item.IsHired = IsHired(item.Id);

                return new ObjectResult(new HetsResponse(item));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Searches Equipment
        /// </summary>
        /// <remarks>Used for the equipment search page.</remarks>
        /// <param name="localareas">Local Areas (array of id numbers)</param>
        /// <param name="types">Equipment Types (array of id numbers)</param>
        /// <param name="equipmentAttachment">Equipment Attachments </param>
        /// <param name="owner"></param>
        /// <param name="status">Status</param>
        /// <param name="hired">Hired</param>
        /// <param name="notverifiedsincedate">Not Verified Since Date</param>
        /// <param name="equipmentId"></param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentSearchGetAsync(string localareas, string types, string equipmentAttachment,
            int? owner, string status, bool? hired, DateTime? notverifiedsincedate, string equipmentId = null)
        {
            int?[] localareasArray = ParseIntArray(localareas);
            int?[] typesArray = ParseIntArray(types);

            // **********************************************************************
            // get initial resultset - results must be limited to user's dsitrict
            // **********************************************************************
            int? districtId = _context.GetDistrictIdByUserId(GetCurrentUserId()).Single();

            IQueryable<Equipment> data = _context.Equipments.AsNoTracking()
                .Include(x => x.LocalArea)
                .Include(x => x.DistrictEquipmentType)
                    .ThenInclude(y => y.EquipmentType)
                .Include(x => x.Owner)
                .Include(x => x.EquipmentAttachments)
                .Include(x => x.RentalAgreements)
                .Where(x => x.LocalArea.ServiceArea.DistrictId.Equals(districtId));

            // **********************************************************************
            // filter results based on search critera
            // **********************************************************************
            if (localareasArray != null && localareasArray.Length > 0)
            {
                data = data.Where(x => localareasArray.Contains(x.LocalArea.Id));
            }

            if (equipmentAttachment != null)
            {
                data = data.Where(x => x.EquipmentAttachments.Any(y => y.TypeName.ToLower().Contains(equipmentAttachment.ToLower())));
            }

            if (owner != null)
            {
                data = data.Where(x => x.Owner.Id == owner);
            }

            if (status != null)
            {
                data = data.Where(x => String.Equals(x.Status, status, StringComparison.CurrentCultureIgnoreCase));
            }

            // is the equipment hired (search criteria)
            if (hired == true)
            {
                IQueryable<int?> hiredEquipmentQuery = _context.RentalAgreements
                    .Where(x => x.Equipment.LocalArea.ServiceArea.DistrictId.Equals(districtId))
                    .Where(agreement => agreement.Status == "Active")
                    .Select(agreement => agreement.EquipmentId)
                    .Distinct();

                data = data.Where(e => hiredEquipmentQuery.Contains(e.Id));
            }

            if (typesArray != null && typesArray.Length > 0)
            {
                data = data.Where(x => typesArray.Contains(x.DistrictEquipmentType.Id));
            }

            if (notverifiedsincedate != null)
            {
                data = data.Where(x => x.LastVerifiedDate < notverifiedsincedate);
            }

            // Ministry refer to the EquipmentCode as the "equipmentId" - its not the db id
            if (equipmentId != null)
            {
                data = data.Where(x => x.EquipmentCode.ToLower().Contains(equipmentId.ToLower()));
            }

            // **********************************************************************
            // convert Equipment Model to View Model
            // **********************************************************************
            SeniorityScoringRules scoringRules = new SeniorityScoringRules(_configuration);
            List<EquipmentViewModel> result = new List<EquipmentViewModel>();

            foreach (Equipment item in data)
            {
                result.Add(item.ToViewModel(scoringRules));
            }

            // return to the client
            return new ObjectResult(new HetsResponse(result));
        }

        /// <summary>
        /// Get the number of blocks for this type of equipment
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private int GetNumberOfBlocks(Equipment item)
        {
            int numberOfBlocks = -1;

            try
            {
                SeniorityScoringRules scoringRules = new SeniorityScoringRules(_configuration);

                numberOfBlocks = item.DistrictEquipmentType.EquipmentType.IsDumpTruck ?
                    scoringRules.GetTotalBlocks("DumpTruck") + 1 : scoringRules.GetTotalBlocks() + 1;
            }
            catch
            {
                // do nothing
            }

            return numberOfBlocks;
        }

        # region Clone Equipment Agreements

        /// <summary>
        /// Get renatal agreements associated with an equipment id
        /// </summary>
        /// <param name="id">id of Equipment to fetch agreements for</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdGetAgreementsAsync(int id)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                List<RentalAgreement> result = _context.RentalAgreements.AsNoTracking()
                    .Include(x => x.Equipment)
                        .ThenInclude(d => d.DistrictEquipmentType)
                    .Include(e => e.Equipment)
                        .ThenInclude(a => a.EquipmentAttachments)
                    .Include(e => e.Project)
                    .Where(x => x.EquipmentId == id)
                    .ToList();

                // remove all of the additional agreements being returned
                foreach (RentalAgreement agreement in result)
                {
                    agreement.Project.RentalAgreements = null;
                }

                return new ObjectResult(new HetsResponse(result));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Update a rental agreement by cloning a previous equipment's rental agreement
        /// </summary>
        /// <param name="id">Equipment id</param>
        /// <param name="item"></param>
        /// <response code="200">Rental Agreement updated</response>
        public virtual IActionResult EquipmentRentalAgreementClonePostAsync(int id, EquipmentRentalAgreementClone item)
        {
            if (item != null && id == item.EquipmentId)
            {
                bool exists = _context.Equipments.Any(a => a.Id == id);

                if (!exists)
                {
                    // record not found - equipment
                    return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
                }

                List<RentalAgreement> agreements = _context.RentalAgreements
                    .Include(x => x.Equipment)
                        .ThenInclude(d => d.DistrictEquipmentType)
                    .Include(e => e.Equipment)
                        .ThenInclude(a => a.EquipmentAttachments)
                    .Include(x =>x .RentalAgreementRates)
                    .Include(x => x.RentalAgreementConditions)
                    .Include(x => x.TimeRecords)
                    .Where(x => x.EquipmentId == id)
                    .ToList();

                // check that the rental agreements exist
                exists = agreements.Any(a => a.Id == item.RentalAgreementId);

                if (!exists)
                {
                    // (RENTAL AGREEMENT) record not found
                    return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
                }

                // check that the rental agreement to clone exist
                exists = agreements.Any(a => a.Id == item.AgreementToCloneId);

                if (!exists)
                {
                    // (RENTAL AGREEMENT) record not found
                    return new ObjectResult(new HetsResponse("HETS-11", ErrorViewModel.GetDescription("HETS-11", _configuration)));
                }

                int agreementToCloneIndex = agreements.FindIndex(a => a.Id == item.AgreementToCloneId);
                int newRentalagreementIndex = agreements.FindIndex(a => a.Id == item.RentalAgreementId);

                // ******************************************************************
                // Business Rules in the backend:
                // *Can't clone into an Agreement if it isn't Active
                // *Can't clone into an Agreement if it has existing time records
                // ******************************************************************
                if (!agreements[newRentalagreementIndex].Status
                    .Equals("Active", StringComparison.InvariantCultureIgnoreCase))
                {
                    // (RENTAL AGREEMENT) is not active
                    return new ObjectResult(new HetsResponse("HETS-12", ErrorViewModel.GetDescription("HETS-12", _configuration)));
                }

                if (agreements[newRentalagreementIndex].TimeRecords != null &&
                    agreements[newRentalagreementIndex].TimeRecords.Count > 0)
                {
                    // (RENTAL AGREEMENT) has tme records
                    return new ObjectResult(new HetsResponse("HETS-13", ErrorViewModel.GetDescription("HETS-13", _configuration)));
                }

                // ******************************************************************
                // clone agreement
                // ******************************************************************
                // update agreement attributes
                agreements[newRentalagreementIndex].EquipmentRate =
                    agreements[agreementToCloneIndex].EquipmentRate;

                agreements[newRentalagreementIndex].Note =
                    agreements[agreementToCloneIndex].Note;

                agreements[newRentalagreementIndex].RateComment =
                    agreements[agreementToCloneIndex].RateComment;

                agreements[newRentalagreementIndex].RatePeriod =
                    agreements[agreementToCloneIndex].RatePeriod;

                // update rates
                agreements[newRentalagreementIndex].RentalAgreementRates = null;

                foreach (RentalAgreementRate rate in agreements[agreementToCloneIndex].RentalAgreementRates)
                {
                    RentalAgreementRate temp = new RentalAgreementRate
                    {
                        Comment = rate.Comment,
                        ComponentName = rate.ComponentName,
                        Rate = rate.Rate,
                        RatePeriod = rate.RatePeriod,
                        IsIncludedInTotal = rate.IsIncludedInTotal,
                        IsAttachment = rate.IsAttachment,
                        PercentOfEquipmentRate = rate.PercentOfEquipmentRate
                    };

                    if (agreements[newRentalagreementIndex].RentalAgreementRates == null)
                    {
                        agreements[newRentalagreementIndex].RentalAgreementRates =
                            new List<RentalAgreementRate>();
                    }

                    agreements[newRentalagreementIndex].RentalAgreementRates.Add(temp);
                }

                // update conditions
                agreements[newRentalagreementIndex].RentalAgreementConditions = null;

                foreach (RentalAgreementCondition condition in agreements[agreementToCloneIndex].RentalAgreementConditions)
                {
                    RentalAgreementCondition temp = new RentalAgreementCondition
                    {
                        Comment = condition.Comment,
                        ConditionName = condition.ConditionName
                    };

                    if (agreements[newRentalagreementIndex].RentalAgreementConditions == null)
                    {
                        agreements[newRentalagreementIndex].RentalAgreementConditions =
                            new List<RentalAgreementCondition>();
                    }

                    agreements[newRentalagreementIndex].RentalAgreementConditions.Add(temp);
                }

                // save the changes
                _context.SaveChanges();

                // ******************************************************************
                // return updated rental agreement to update the screen
                // ******************************************************************
                RentalAgreement result = _context.RentalAgreements.AsNoTracking()
                    .Include(x => x.Equipment)
                        .ThenInclude(y => y.Owner)
                    .Include(x => x.Equipment)
                        .ThenInclude(y => y.DistrictEquipmentType)
                            .ThenInclude(d => d.EquipmentType)
                    .Include(x => x.Equipment)
                        .ThenInclude(y => y.EquipmentAttachments)
                    .Include(x => x.Equipment)
                        .ThenInclude(y => y.LocalArea.ServiceArea.District.Region)
                    .Include(x => x.Project)
                        .ThenInclude(p => p.District.Region)
                    .Include(x => x.RentalAgreementConditions)
                    .Include(x => x.RentalAgreementRates)
                    .Include(x => x.TimeRecords)
                    .First(a => a.Id == item.RentalAgreementId);

                return new ObjectResult(new HetsResponse(result));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        #endregion

        #region Duplicate Equiment

        /// <summary>
        /// Get all duplicate equipment records
        /// </summary>
        /// <param name="id">id of Equipment</param>
        /// <param name="serialNumber">Serial Number of Equipment</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdEquipmentduplicatesGetAsync(int id, string serialNumber)
        {
            bool exists = _context.Equipments.Any(x => x.Id == id);

            // id = 0 -> need to allow for new records too
            if (exists || id == 0)
            {
                List<Equipment> result = _context.Equipments.AsNoTracking()
                    .Include(x => x.LocalArea.ServiceArea.District)
                    .Include(x => x.Owner)
                    .Where(x => x.SerialNumber == serialNumber &&
                                x.Id != id &&
                                x.ArchiveCode == "N").ToList();

                List<DuplicateEquipmentViewModel> duplicates = new List<DuplicateEquipmentViewModel>();
                int idCount = -1;

                foreach (Equipment equipment in result)
                {
                    idCount++;

                    DuplicateEquipmentViewModel duplicate = new DuplicateEquipmentViewModel
                    {
                        Id = idCount,
                        SerialNumber = serialNumber,
                        DuplicateEquipment = equipment,
                        DistrictName = ""
                    };

                    if (equipment.LocalArea.ServiceArea.District != null &&
                        !string.IsNullOrEmpty(equipment.LocalArea.ServiceArea.District.Name))
                    {
                        duplicate.DistrictName = equipment.LocalArea.ServiceArea.District.Name;
                    }

                    duplicates.Add(duplicate);
                }

                // return to the client
                return new ObjectResult(new HetsResponse(duplicates));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        #endregion

        #region Recalculate Seniority

        /// <summary>
        /// Recalculates seniority for a specific local area and equipment type
        /// </summary>
        public static void EquipmentRecalcSeniority(int localAreaId, int districtEquipmentTypeId, DbAppContext context, IConfiguration configuration)
        {
            // check if the local area and equipment are valid
            bool exists = context.LocalAreas.Any(a => a.Id == localAreaId);

            if (!exists)
            {
                throw new ArgumentException("Local Area is invalid");
            }

            exists = context.DistrictEquipmentTypes.Any(a => a.Id == districtEquipmentTypeId);

            if (!exists)
            {
                throw new ArgumentException("District Equipment Type is invalid");
            }

            // get the local area
            LocalArea localArea = context.LocalAreas
                .First(x => x.Id == localAreaId);

            // get the equipment
            DistrictEquipmentType districtEquipmentType = context.DistrictEquipmentTypes
                .Include(x => x.EquipmentType)
                .First(x => x.Id == districtEquipmentTypeId);

            // recalc the seniority list
            context.CalculateSeniorityList(localArea.Id, districtEquipmentType.Id, districtEquipmentType.EquipmentType.Id, configuration);
        }

        /// <summary>
        /// Recalculates seniority for an entire region
        /// </summary>
        /// <remarks>Used to calculate seniority for all database records</remarks>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentRecalcSeniorityGetAsync(int region)
        {
            // check if the region is valid
            bool exists = _context.Regions.Any(a => a.Id == region);

            // region not found
            if (!exists)
            {
                return new ObjectResult(new HetsResponse("HETS-03", ErrorViewModel.GetDescription("HETS-03", _configuration)));
            }

            // get all local areas for this region
            IQueryable<LocalArea> localAreas = _context.Equipments
                .Include(x => x.LocalArea)
                .Where(x => x.LocalArea.ServiceArea.District.Region.Id == region)
                .Select(x => x.LocalArea)
                .Distinct();

            foreach (LocalArea localArea in localAreas)
            {
                // get all district equipment types for this region
                IQueryable<DistrictEquipmentType> equipmentTypes = _context.Equipments
                    .Include(x => x.DistrictEquipmentType)
                    .Where(x => x.LocalArea.Id == localArea.Id)
                    .Select(x => x.DistrictEquipmentType)
                    .Distinct();

                foreach (DistrictEquipmentType districtEquipmentType in equipmentTypes)
                {
                    _context.CalculateSeniorityList(localArea.Id, districtEquipmentType.Id, districtEquipmentType.EquipmentType.Id, _configuration);
                }
            }

            return new ObjectResult("Done Recalc");
        }

        #endregion

        #region Functions to setup/fix the Equipment Record (cleanup record submitted by UI for update/insert)

        /// <summary>
        /// Cleanup new equipment record for insert
        /// </summary>
        /// <param name="item"></param>
        private void AdjustRecord(Equipment item)
        {
            if (item != null)
            {
                // adjust the record to allow it to be updated / inserted
                if (item.LocalArea != null)
                {
                    item.LocalArea = _context.LocalAreas.FirstOrDefault(a => a.Id == item.LocalArea.Id);
                }

                // DistrictEquiptmentType
                if (item.DistrictEquipmentType != null)
                {
                    item.DistrictEquipmentType = _context.DistrictEquipmentTypes.FirstOrDefault(a => a.Id == item.DistrictEquipmentType.Id);
                }

                // owner
                if (item.Owner != null)
                {
                    item.Owner = _context.Owners
                        .Include(x => x.EquipmentList)
                        .FirstOrDefault(a => a.Id == item.Owner.Id);
                }

                // EquipmentAttachments is a list
                if (item.EquipmentAttachments != null)
                {
                    for (int i = 0; i < item.EquipmentAttachments.Count; i++)
                    {
                        if (item.EquipmentAttachments[i] != null)
                        {
                            item.EquipmentAttachments[i] = _context.EquipmentAttachments.FirstOrDefault(a => a.Id == item.EquipmentAttachments[i].Id);
                        }
                    }
                }

                // Attachments is a list
                if (item.Attachments != null)
                {
                    for (int i = 0; i < item.Attachments.Count; i++)
                    {
                        if (item.Attachments[i] != null)
                        {
                            item.Attachments[i] = _context.Attachments.FirstOrDefault(a => a.Id == item.Attachments[i].Id);
                        }
                    }
                }

                // Notes is a list
                if (item.Notes != null)
                {
                    for (int i = 0; i < item.Notes.Count; i++)
                    {
                        if (item.Notes[i] != null)
                        {
                            item.Notes[i] = _context.Notes.FirstOrDefault(a => a.Id == item.Notes[i].Id);
                        }
                    }
                }

                // History is a list
                if (item.History != null)
                {
                    for (int i = 0; i < item.History.Count; i++)
                    {
                        if (item.History[i] != null)
                        {
                            item.History[i] = _context.Historys.FirstOrDefault(a => a.Id == item.History[i].Id);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Generate an equipment code
        /// </summary>
        /// <param name="ownerEquipmentCodePrefix"></param>
        /// <param name="equipmentNumber"></param>
        /// <returns></returns>
        private string GenerateEquipmentCode(string ownerEquipmentCodePrefix, int equipmentNumber)
        {
            string result = ownerEquipmentCodePrefix + "-" + equipmentNumber.ToString("D4");
            return result;
        }

        /// <summary>
        /// Set the Equipment fields for a new record for fields that are not provided by the front end
        /// </summary>
        /// <param name="item"></param>
        private void SetNewRecordFields(Equipment item)
        {
            item.ReceivedDate = DateTime.UtcNow;
            item.LastVerifiedDate = DateTime.UtcNow;

            // per JIRA HETS-536
            item.ApprovedDate = DateTime.UtcNow;

            item.Seniority = 0.0F;
            item.YearsOfService = 0.0F;
            item.ServiceHoursLastYear = 0.0F;
            item.ServiceHoursTwoYearsAgo = 0.0F;
            item.ServiceHoursThreeYearsAgo = 0.0F;
            item.ArchiveCode = "N";
            item.IsSeniorityOverridden = false;

            // new equipment MUST always start as unaproved - it isn't assigned to any block yet
            item.Status = "Unapproved";

            // generate a new equipment code.
            if (item.Owner != null)
            {
                int equipmentNumber = 1;

                if (item.Owner.EquipmentList != null)
                {
                    bool looking = true;
                    equipmentNumber = item.Owner.EquipmentList.Count + 1;

                    // generate a unique equipment number
                    while (looking)
                    {
                        string candidate = GenerateEquipmentCode(item.Owner.OwnerCode, equipmentNumber);
                        if ((item.Owner.EquipmentList).Any(x => x.EquipmentCode == candidate))
                        {
                            equipmentNumber++;
                        }
                        else
                        {
                            looking = false;
                        }
                    }
                }

                // set the equipment code
                item.EquipmentCode = GenerateEquipmentCode(item.Owner.OwnerCode, equipmentNumber);
            }
        }

        #endregion

        #region Equipment History

        /// <summary>
        /// Get history associated with an equipment record
        /// </summary>
        /// <remarks>Returns History for a particular Equipment</remarks>
        /// <param name="id">id of SchoolBus to fetch History for</param>
        /// <param name="offset"></param>
        /// <param name="limit"></param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdHistoryGetAsync(int id, int? offset, int? limit)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                return new ObjectResult(new HetsResponse(GetHistoryRecords(id, offset, limit)));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        private List<HistoryViewModel> GetHistoryRecords(int id, int? offset, int? limit)
        {
            Equipment equipment = _context.Equipments.AsNoTracking()
                .Include(x => x.History)
                .First(a => a.Id == id);

            List<History> data = equipment.History.OrderByDescending(y => y.AppLastUpdateTimestamp).ToList();

            if (offset == null)
            {
                offset = 0;
            }

            if (limit == null)
            {
                limit = data.Count - offset;
            }

            List<HistoryViewModel> result = new List<HistoryViewModel>();

            for (int i = (int)offset; i < data.Count && i < offset + limit; i++)
            {
                result.Add(data[i].ToViewModel());
            }

            return result;
        }

        /// <summary>
        /// Create history record associated with equipment
        /// </summary>
        /// <remarks>Add a History record to the Equipment</remarks>
        /// <param name="id">id of Equipment to add History for</param>
        /// <param name="item"></param>
        /// <response code="200">OK</response>
        /// <response code="201">History created</response>
        public virtual IActionResult EquipmentIdHistoryPostAsync(int id, History item)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                Equipment equipment = _context.Equipments.AsNoTracking()
                    .First(a => a.Id == id);

                History history = new History
                {
                    Id = 0,
                    HistoryText = item.HistoryText,
                    CreatedDate = item.CreatedDate,
                    EquipmentId = equipment.Id
                };

                _context.Historys.Add(history);
                _context.SaveChanges();
            }

            return new ObjectResult(new HetsResponse(GetHistoryRecords(id, null, null)));
        }

        #endregion

        #region Equipment Attachments

        /// <summary>
        /// Get "equipment attachments" associated with an equipment record
        /// </summary>
        /// <param name="id">id of Equipment to fetch EquipmentAttachments for</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdEquipmentattachmentsGetAsync(int id)
        {
            bool exists = _context.Equipments.Any(x => x.Id == id);

            if (exists)
            {
                IQueryable<EquipmentAttachment> result = _context.EquipmentAttachments
                    .Include(x => x.Equipment)
                    .Where(x => x.Equipment.Id == id);

                return new ObjectResult(new HetsResponse(result));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        #endregion

        #region Attachments

        /// <summary>
        /// Get attachments associated with an equipment record
        /// </summary>
        /// <remarks>Returns attachments for a particular Equipment</remarks>
        /// <param name="id">id of Equipment to fetch attachments for</param>
        /// <response code="200">OK</response>
        /// <response code="404">Equipment not found</response>
        public virtual IActionResult EquipmentIdAttachmentsGetAsync(int id)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                Equipment equipment = _context.Equipments
                    .Include(x => x.Attachments)
                    .First(a => a.Id == id);

                List<AttachmentViewModel> result = MappingExtensions.GetAttachmentListAsViewModel(equipment.Attachments);

                return new ObjectResult(new HetsResponse(result));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        #endregion

        #region Equipment Note Records

        /// <summary>
        /// Get note records associated with equipment
        /// </summary>
        /// <param name="id">id of Equipment to fetch Notes for</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdNotesGetAsync(int id)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists)
            {
                Equipment equipment = _context.Equipments.AsNoTracking()
                    .Include(x => x.Notes)
                    .First(x => x.Id == id);

                List<Note> notes = new List<Note>();

                foreach (Note note in equipment.Notes)
                {
                    if (note.IsNoLongerRelevant == false)
                    {
                        notes.Add(note);
                    }
                }

                return new ObjectResult(new HetsResponse(notes));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Update or create a note associated with a equipment
        /// </summary>
        /// <remarks>Update a Equipment's Notes</remarks>
        /// <param name="id">id of Equipment to update Notes for</param>
        /// <param name="item">Equipment Note</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdNotesPostAsync(int id, Note item)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists && item != null)
            {
                Equipment equipment = _context.Equipments
                    .Include(x => x.Notes)
                    .First(x => x.Id == id);

                // ******************************************************************
                // add or update note
                // ******************************************************************
                if (item.Id > 0)
                {
                    int noteIndex = equipment.Notes.FindIndex(a => a.Id == item.Id);

                    if (noteIndex < 0)
                    {
                        // record not found
                        return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
                    }

                    equipment.Notes[noteIndex].Text = item.Text;
                    equipment.Notes[noteIndex].IsNoLongerRelevant = item.IsNoLongerRelevant;
                }
                else  // add note
                {
                    equipment.Notes.Add(item);
                }

                _context.SaveChanges();

                // *************************************************************
                // return updated time records
                // *************************************************************
                List<Note> notes = new List<Note>();

                foreach (Note note in equipment.Notes)
                {
                    if (note.IsNoLongerRelevant == false)
                    {
                        notes.Add(note);
                    }
                }

                return new ObjectResult(new HetsResponse(notes));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        /// <summary>
        /// Update or create an array of notes associated with a equipment
        /// </summary>
        /// <remarks>Update a Equipment's Notes</remarks>
        /// <param name="id">id of Equipment to update Notes for</param>
        /// <param name="items">Array of Equipment Notes</param>
        /// <response code="200">OK</response>
        public virtual IActionResult EquipmentIdNotesBulkPostAsync(int id, Note[] items)
        {
            bool exists = _context.Equipments.Any(a => a.Id == id);

            if (exists && items != null)
            {
                Equipment equipment = _context.Equipments
                    .Include(x => x.Notes)
                    .First(x => x.Id == id);

                // process each note
                foreach (Note item in items)
                {
                    // ******************************************************************
                    // add or update note
                    // ******************************************************************
                    if (item.Id > 0)
                    {
                        int noteIndex = equipment.Notes.FindIndex(a => a.Id == item.Id);

                        if (noteIndex < 0)
                        {
                            // record not found
                            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
                        }

                        equipment.Notes[noteIndex].Text = item.Text;
                        equipment.Notes[noteIndex].IsNoLongerRelevant = item.IsNoLongerRelevant;
                    }
                    else  // add note
                    {
                        equipment.Notes.Add(item);
                    }

                    _context.SaveChanges();
                }

                _context.SaveChanges();

                // *************************************************************
                // return updated notes
                // *************************************************************
                List<Note> notes = new List<Note>();

                foreach (Note note in equipment.Notes)
                {
                    if (note.IsNoLongerRelevant == false)
                    {
                        notes.Add(note);
                    }
                }

                return new ObjectResult(new HetsResponse(notes));
            }

            // record not found
            return new ObjectResult(new HetsResponse("HETS-01", ErrorViewModel.GetDescription("HETS-01", _configuration)));
        }

        #endregion

        #region Equipment Seniority List

        /// <summary>
        /// Get a pdf version of the seniority list
        /// </summary>
        /// <remarks>Returns a PDF version of the seniority list</remarks>
        /// <param name="localareas">Local Areas (array of id numbers)</param>
        /// <param name="types">Equipment Types (array of id numbers)</param>
        /// <response code="200">OK</response>
        public IActionResult EquipmentSeniorityListPdfGetAsync(string localareas, string types)
        {
            _logger.LogInformation("Equipment Seniority List Pdf");

            int?[] localareasArray = ParseIntArray(localareas);
            int?[] typesArray = ParseIntArray(types);

            int? districtId = _context.GetDistrictIdByUserId(GetCurrentUserId()).Single();

            IQueryable<Equipment> data = _context.Equipments.AsNoTracking()
                .Include(x => x.LocalArea)
                    .ThenInclude(y => y.ServiceArea)
                        .ThenInclude(z => z.District)
                .Include(x => x.DistrictEquipmentType)
                    .ThenInclude(y => y.EquipmentType)
                .Include(x => x.Owner)
                .Include(x => x.RentalAgreements)
                .Where(x => x.LocalArea.ServiceArea.DistrictId.Equals(districtId) &&
                            x.Status == Equipment.StatusApproved)
                .OrderBy(x => x.LocalArea).ThenBy(x => x.DistrictEquipmentType);

            if (localareasArray != null && localareasArray.Length > 0)
            {
                data = data.Where(x => localareasArray.Contains(x.LocalArea.Id));
            }

            if (typesArray != null && typesArray.Length > 0)
            {
                data = data.Where(x => typesArray.Contains(x.DistrictEquipmentType.Id));
            }

            // **********************************************************************
            // determine the year header values
            // * start by getting the current fiscal year
            // **********************************************************************
            // determine end of current fscal year
            DateTime fiscalEnd;

            if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3)
            {
                fiscalEnd = new DateTime(DateTime.UtcNow.Year, 3, 31);
            }
            else
            {
                fiscalEnd = new DateTime(DateTime.UtcNow.AddYears(1).Year, 3, 31);
            }

            string yearMinus1 = string.Format("{0}/{1}", fiscalEnd.AddYears(-1).Year.ToString(),
                fiscalEnd.Year.ToString().Substring(2, 2));

            string yearMinus2 = string.Format("{0}/{1}", fiscalEnd.AddYears(-2).Year.ToString(),
                fiscalEnd.AddYears(-1).Year.ToString().Substring(2, 2));

            string yearMinus3 = string.Format("{0}/{1}", fiscalEnd.AddYears(-3).Year.ToString(),
                fiscalEnd.AddYears(-2).Year.ToString().Substring(2, 2));

            // **********************************************************************
            // convert Equipment Model to Pdf View Model
            // **********************************************************************
            SeniorityListPdfViewModel seniorityList = new SeniorityListPdfViewModel();
            SeniorityScoringRules scoringRules = new SeniorityScoringRules(_configuration);
            SeniorityListRecord listRecord = new SeniorityListRecord();

            // get last called data
            LocalAreaRotationList rotation = null;

            foreach (Equipment item in data)
            {
                if (listRecord.LocalAreaName != item.LocalArea.Name ||
                    listRecord.DistrictEquipmentTypeName != item.DistrictEquipmentType.DistrictEquipmentName)
                {
                    rotation = _context.LocalAreaRotationLists.AsNoTracking()
                        .Include(x => x.LocalArea)
                        .Include(x => x.DistrictEquipmentType)
                        .FirstOrDefault(x => x.LocalArea.Id == item.LocalArea.Id &&
                                             x.DistrictEquipmentType.Id == item.DistrictEquipmentType.Id);

                    if (!string.IsNullOrEmpty(listRecord.LocalAreaName))
                    {
                        if (seniorityList.SeniorityListRecords == null)
                        {
                            seniorityList.SeniorityListRecords = new List<SeniorityListRecord>();
                        }

                        seniorityList.SeniorityListRecords.Add(listRecord);
                    }

                    listRecord = new SeniorityListRecord
                    {
                        LocalAreaName = item.LocalArea.Name,
                        DistrictEquipmentTypeName = item.DistrictEquipmentType.DistrictEquipmentName,
                        YearMinus1 = yearMinus1,
                        YearMinus2 = yearMinus2,
                        YearMinus3 = yearMinus3,
                        SeniorityList = new List<SeniorityViewModel>()
                    };

                    if (item.LocalArea.ServiceArea != null &&
                        item.LocalArea.ServiceArea.District != null)
                    {
                        listRecord.DistrictName = item.LocalArea.ServiceArea.District.Name;
                    }
                }

                listRecord.SeniorityList.Add(item.ToSeniorityViewModel(scoringRules, rotation, _context));
            }

            // add last record
            if (!string.IsNullOrEmpty(listRecord.LocalAreaName))
            {
                if (seniorityList.SeniorityListRecords == null)
                {
                    seniorityList.SeniorityListRecords = new List<SeniorityListRecord>();
                }

                seniorityList.SeniorityListRecords.Add(listRecord);
            }

            // sort seniority lists
            foreach (SeniorityListRecord list in seniorityList.SeniorityListRecords)
            {
                list.SeniorityList = list.SeniorityList.OrderByDescending(x => x.SenioritySortOrder).ToList();
            }

            // fix the ask next (if no rotation list existed
            foreach (SeniorityListRecord list in seniorityList.SeniorityListRecords)
            {
                bool askNextExists = list.SeniorityList.Exists(x => x.LastCalled == "Y");

                if (!askNextExists && list.SeniorityList.Count > 0)
                {
                    list.SeniorityList[0].LastCalled = "Y";
                }
            }

            // **********************************************************************
            // create the payload and call the pdf service
            // **********************************************************************
            string payload = JsonConvert.SerializeObject(seniorityList, new JsonSerializerSettings
            {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting = Formatting.Indented,
                DateFormatHandling = DateFormatHandling.IsoDateFormat,
                DateTimeZoneHandling = DateTimeZoneHandling.Utc
            });

            _logger.LogInformation("Equipment Seniority List Pdf - Payload Length: {0}", payload.Length);

            // pass the request on to the Pdf Micro Service
            string pdfHost = _configuration["PDF_SERVICE_NAME"];
            string pdfUrl = _configuration.GetSection("Constants:SeniorityListPdfUrl").Value;
            string targetUrl = pdfHost + pdfUrl;

            // generate pdf document name [unique portion only]
            string fileName = "HETS_SeniorityList";

            targetUrl = targetUrl + "/" + fileName;

            _logger.LogInformation("Equipment Seniority List Pdf - HETS Pdf Service Url: {0}", targetUrl);

            // call the microservice
            try
            {
                HttpClient client = new HttpClient();
                StringContent stringContent = new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json");

                _logger.LogInformation("Equipment Seniority List Pdf - Calling HETS Pdf Service");
                HttpResponseMessage response = client.PostAsync(targetUrl, stringContent).Result;

                // success
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    _logger.LogInformation("Equipment Seniority List Pdf - HETS Pdf Service Response: OK");

                    var pdfResponseBytes = GetPdf(response);

                    // convert to string and log
                    string pdfResponse = Encoding.Default.GetString(pdfResponseBytes);

                    fileName = fileName + ".pdf";

                    _logger.LogInformation("Equipment Seniority List Pdf - HETS Pdf Filename: {0}", fileName);
                    _logger.LogInformation("Equipment Seniority List Pdf - HETS Pdf Size: {0}", pdfResponse.Length);

                    // return content
                    FileContentResult pdfResult = new FileContentResult(pdfResponseBytes, "application/pdf")
                    {
                        FileDownloadName = fileName
                    };

                    return pdfResult;
                }

                _logger.LogInformation("Equipment Seniority List Pdf - HETS Pdf Service Response: {0}", response.StatusCode);

                // problem occured
                return new ObjectResult(new HetsResponse("HETS-05", ErrorViewModel.GetDescription("HETS-05", _configuration)));
            }
            catch (Exception ex)
            {
                Debug.Write("Error generating pdf: " + ex.Message);
                return new ObjectResult(new HetsResponse("HETS-05", ErrorViewModel.GetDescription("HETS-05", _configuration)));
            }
        }

        private static byte[] GetPdf(HttpResponseMessage response)
        {
            try
            {
                var pdfResponseBytes = response.Content.ReadAsByteArrayAsync();
                pdfResponseBytes.Wait();

                return pdfResponseBytes.Result;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        #endregion
    }
}


text:
ubuntu-systemtap-node
=====================

Scripts for using systemtap on Ubuntu to analyse node.js

redpajama_set_name: RedPajamaGithub


text:
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE

using System;
using osu.Framework.Configuration;
using osu.Framework.Platform;
using osu.Game.Modes;

namespace osu.Game.Configuration
{
    public class OsuConfigManager : ConfigManager<OsuConfig>
    {
        protected override void InitialiseDefaults()
        {
#pragma warning disable CS0612 // Type or member is obsolete

            Set(OsuConfig.Username, string.Empty);
            Set(OsuConfig.Token, string.Empty);

            Set(OsuConfig.PlayMode, PlayMode.Osu);

            Set(OsuConfig.AudioDevice, string.Empty);
            Set(OsuConfig.SavePassword, false);
            Set(OsuConfig.SaveUsername, true);

            Set(OsuConfig.CursorSize, 1.0, 0.5f, 2);
            Set(OsuConfig.DimLevel, 30, 0, 100);

            Set(OsuConfig.MouseDisableButtons, false);

            Set(OsuConfig.SnakingInSliders, true);
            Set(OsuConfig.SnakingOutSliders, false);

            //todo: implement all settings below this line (remove the Disabled set when doing so).

            Set(OsuConfig.MouseSpeed, 1.0).Disabled = true;
            Set(OsuConfig.BeatmapDirectory, @"Songs").Disabled = true; // TODO: use thi.Disabled = trues
            Set(OsuConfig.AllowPublicInvites, true).Disabled = true;
            Set(OsuConfig.AutoChatHide, true).Disabled = true;
            Set(OsuConfig.AutomaticDownload, true).Disabled = true;
            Set(OsuConfig.AutomaticDownloadNoVideo, false).Disabled = true;
            Set(OsuConfig.BlockNonFriendPM, false).Disabled = true;
            Set(OsuConfig.BloomSoftening, false).Disabled = true;
            Set(OsuConfig.BossKeyFirstActivation, true).Disabled = true;
            Set(OsuConfig.ChatAudibleHighlight, true).Disabled = true;
            Set(OsuConfig.ChatChannels, string.Empty).Disabled = true;
            Set(OsuConfig.ChatFilter, false).Disabled = true;
            Set(OsuConfig.ChatHighlightName, true).Disabled = true;
            Set(OsuConfig.ChatMessageNotification, true).Disabled = true;
            Set(OsuConfig.ChatLastChannel, string.Empty).Disabled = true;
            Set(OsuConfig.ChatRemoveForeign, false).Disabled = true;
            //Set(OsuConfig.ChatSortMode, UserSortMode.Rank).Disabled = true;
            Set(OsuConfig.ComboBurst, true).Disabled = true;
            Set(OsuConfig.ComboFire, false).Disabled = true;
            Set(OsuConfig.ComboFireHeight, 3).Disabled = true;
            Set(OsuConfig.ConfirmExit, false).Disabled = true;
            Set(OsuConfig.AutoSendNowPlaying, true).Disabled = true;
            Set(OsuConfig.AutomaticCursorSizing, false).Disabled = true;
            Set(OsuConfig.Display, 1).Disabled = true;
            Set(OsuConfig.DisplayCityLocation, false).Disabled = true;
            Set(OsuConfig.DistanceSpacingEnabled, true).Disabled = true;
            Set(OsuConfig.EditorTip, 0).Disabled = true;
            Set(OsuConfig.VideoEditor, true).Disabled = true;
            Set(OsuConfig.EditorDefaultSkin, false).Disabled = true;
            Set(OsuConfig.EditorSnakingSliders, true).Disabled = true;
            Set(OsuConfig.EditorHitAnimations, false).Disabled = true;
            Set(OsuConfig.EditorFollowPoints, true).Disabled = true;
            Set(OsuConfig.EditorStacking, true).Disabled = true;
            Set(OsuConfig.ForceSliderRendering, false).Disabled = true;
            Set(OsuConfig.FpsCounter, false).Disabled = true;
            Set(OsuConfig.FrameTimeDisplay, false).Disabled = true;
            Set(OsuConfig.GuideTips, @"").Disabled = true;
            Set(OsuConfig.CursorRipple, false).Disabled = true;
            Set(OsuConfig.HighlightWords, string.Empty).Disabled = true;
            Set(OsuConfig.HighResolution, false).Disabled = true;
            Set(OsuConfig.HitLighting, true).Disabled = true;
            Set(OsuConfig.IgnoreBarline, false).Disabled = true;
            Set(OsuConfig.IgnoreBeatmapSamples, false).Disabled = true;
            Set(OsuConfig.IgnoreBeatmapSkins, false).Disabled = true;
            Set(OsuConfig.IgnoreList, string.Empty).Disabled = true;
            Set(OsuConfig.KeyOverlay, false).Disabled = true;
            Set(OsuConfig.Language, @"unknown").Disabled = true;
            Set(OsuConfig.AllowNowPlayingHighlights, false).Disabled = true;
            Set(OsuConfig.LastVersion, string.Empty).Disabled = true;
            Set(OsuConfig.LastVersionPermissionsFailed, string.Empty).Disabled = true;
            Set(OsuConfig.LoadSubmittedThread, true).Disabled = true;
            Set(OsuConfig.LobbyPlayMode, -1).Disabled = true;
            Set(OsuConfig.ShowInterface, true).Disabled = true;
            Set(OsuConfig.ShowInterfaceDuringRelax, false).Disabled = true;
            Set(OsuConfig.LobbyShowExistingOnly, false).Disabled = true;
            Set(OsuConfig.LobbyShowFriendsOnly, false).Disabled = true;
            Set(OsuConfig.LobbyShowFull, false).Disabled = true;
            Set(OsuConfig.LobbyShowInProgress, true).Disabled = true;
            Set(OsuConfig.LobbyShowPassworded, true).Disabled = true;
            Set(OsuConfig.LogPrivateMessages, false).Disabled = true;
            Set(OsuConfig.LowResolution, false).Disabled = true;
            //Set(OsuConfig.ManiaSpeed, SpeedMania.SPEED_DEFAULT, SpeedMania.SPEED_MIN, SpeedMania.SPEED_MAX).Disabled = true;
            Set(OsuConfig.UsePerBeatmapManiaSpeed, true).Disabled = true;
            Set(OsuConfig.ManiaSpeedBPMScale, true).Disabled = true;
            Set(OsuConfig.MenuTip, 0).Disabled = true;
            Set(OsuConfig.MouseDisableWheel, false).Disabled = true;
            Set(OsuConfig.MouseSpeed, 1, 0.4, 6).Disabled = true;
            Set(OsuConfig.Offset, 0, -300, 300).Disabled = true;
            Set(OsuConfig.ScoreMeterScale, 1, 0.5, 2).Disabled = true;
            //Set(OsuConfig.ScoreMeterScale, 1, 0.5, OsuGame.Tournament ? 10 : 2).Disabled = true;
            Set(OsuConfig.DistanceSpacing, 0.8, 0.1, 6).Disabled = true;
            Set(OsuConfig.EditorBeatDivisor, 1, 1, 16).Disabled = true;
            Set(OsuConfig.EditorGridSize, 32, 4, 32).Disabled = true;
            Set(OsuConfig.EditorGridSizeDesign, 32, 4, 32).Disabled = true;
            Set(OsuConfig.CustomFrameLimit, 240, 240, 999).Disabled = true;
            Set(OsuConfig.MsnIntegration, false).Disabled = true;
            Set(OsuConfig.MyPcSucks, false).Disabled = true;
            Set(OsuConfig.NotifyFriends, true).Disabled = true;
            Set(OsuConfig.NotifySubmittedThread, true).Disabled = true;
            Set(OsuConfig.PopupDuringGameplay, true).Disabled = true;
            Set(OsuConfig.ProgressBarType, ProgressBarType.Pie).Disabled = true;
            Set(OsuConfig.RankType, RankingType.Top).Disabled = true;
            Set(OsuConfig.RefreshRate, 60).Disabled = true;
            Set(OsuConfig.OverrideRefreshRate, Get<int>(OsuConfig.RefreshRate) != 60).Disabled = true;
            //Set(OsuConfig.ScaleMode, ScaleMode.WidescreenConservative).Disabled = true;
            Set(OsuConfig.ScoreboardVisible, true).Disabled = true;
            Set(OsuConfig.ScoreMeter, ScoreMeterType.Error).Disabled = true;
            //Set(OsuConfig.ScoreMeter, OsuGame.Tournament ? ScoreMeterType.Colour : ScoreMeterType.Error).Disabled = true;
            Set(OsuConfig.ScreenshotId, 0).Disabled = true;
            Set(OsuConfig.MenuSnow, false).Disabled = true;
            Set(OsuConfig.MenuTriangles, true).Disabled = true;
            Set(OsuConfig.SongSelectThumbnails, true).Disabled = true;
            Set(OsuConfig.ScreenshotFormat, ScreenshotFormat.Jpg).Disabled = true;
            Set(OsuConfig.ShowReplayComments, true).Disabled = true;
            Set(OsuConfig.ShowSpectators, true).Disabled = true;
            Set(OsuConfig.ShowStoryboard, true).Disabled = true;
            //Set(OsuConfig.Skin, SkinManager.DEFAULT_SKIN).Disabled = true;
            Set(OsuConfig.SkinSamples, true).Disabled = true;
            Set(OsuConfig.SkipTablet, false).Disabled = true;
            Set(OsuConfig.Tablet, false).Disabled = true;
            Set(OsuConfig.UpdatePending, false).Disabled = true;
            Set(OsuConfig.UseSkinCursor, false).Disabled = true;
            Set(OsuConfig.UseTaikoSkin, false).Disabled = true;
            Set(OsuConfig.Video, true).Disabled = true;
            Set(OsuConfig.Wiimote, false).Disabled = true;
            Set(OsuConfig.YahooIntegration, false).Disabled = true;
            Set(OsuConfig.ForceFrameFlush, false).Disabled = true;
            Set(OsuConfig.DetectPerformanceIssues, true).Disabled = true;
            Set(OsuConfig.MenuMusic, true).Disabled = true;
            Set(OsuConfig.MenuVoice, true).Disabled = true;
            Set(OsuConfig.MenuParallax, true).Disabled = true;
            Set(OsuConfig.RawInput, false).Disabled = true;
            Set(OsuConfig.AbsoluteToOsuWindow, Get<bool>(OsuConfig.RawInput)).Disabled = true;
            Set(OsuConfig.ShowMenuTips, true).Disabled = true;
            Set(OsuConfig.HiddenShowFirstApproach, true).Disabled = true;
            Set(OsuConfig.ComboColourSliderBall, true).Disabled = true;
            Set(OsuConfig.AlternativeChatFont, false).Disabled = true;
            Set(OsuConfig.DisplayStarsMaximum, 10.0, 0.0, 10.0).Disabled = true;
            Set(OsuConfig.DisplayStarsMinimum, 0.0, 0.0, 10.0).Disabled = true;
            Set(OsuConfig.ReleaseStream, ReleaseStream.Lazer).Disabled = true;
            Set(OsuConfig.UpdateFailCount, 0).Disabled = true;
            //Set(OsuConfig.TreeSortMode, TreeGroupMode.Show_All).Disabled = true;
            //Set(OsuConfig.TreeSortMode2, TreeSortMode.Title).Disabled = true;
            bool unicodeDefault = false;
            switch (Get<string>(OsuConfig.Language))
            {
                case @"zh":
                case @"ja":
                case @"ko":
                    unicodeDefault = true;
                    break;
            }
            Set(OsuConfig.ShowUnicode, unicodeDefault);
            Set(OsuConfig.PermanentSongInfo, false).Disabled = true;
            Set(OsuConfig.Ticker, false).Disabled = true;
            Set(OsuConfig.CompatibilityContext, false).Disabled = true;
            Set(OsuConfig.CanForceOptimusCompatibility, true).Disabled = true;
            Set(OsuConfig.ConfineMouse, Get<bool>(OsuConfig.ConfineMouseToFullscreen) ?
                ConfineMouseMode.Fullscreen : ConfineMouseMode.Never).Disabled = true;

            GetBindable<bool>(OsuConfig.SavePassword).ValueChanged += delegate
            {
                if (Get<bool>(OsuConfig.SavePassword)) Set(OsuConfig.SaveUsername, true);
            };
            GetBindable<bool>(OsuConfig.SaveUsername).ValueChanged += delegate
            {
                if (!Get<bool>(OsuConfig.SaveUsername)) Set(OsuConfig.SavePassword, false);
            };
#pragma warning restore CS0612 // Type or member is obsolete
        }

        //todo: make a UnicodeString class/struct rather than requiring this helper method.
        public string GetUnicodeString(string nonunicode, string unicode)
            => Get<bool>(OsuConfig.ShowUnicode) ? unicode ?? nonunicode : nonunicode ?? unicode;

        public OsuConfigManager(BasicStorage storage) : base(storage)
        {
        }
    }

    public enum OsuConfig
    {
        // New osu:
        PlayMode,
        Token,
        // Imported from old osu:
        BeatmapDirectory,
        AllowPublicInvites,
        AutoChatHide,
        AutomaticDownload,
        AutomaticDownloadNoVideo,
        BlockNonFriendPM,
        Bloom,
        BloomSoftening,
        BossKeyFirstActivation,
        ChatAudibleHighlight,
        ChatChannels,
        ChatFilter,
        ChatHighlightName,
        ChatMessageNotification,
        ChatLastChannel,
        ChatRemoveForeign,
        ChatSortMode,
        ComboBurst,
        ComboFire,
        ComboFireHeight,
        ConfirmExit,
        AutoSendNowPlaying,
        CursorSize,
        AutomaticCursorSizing,
        DimLevel,
        Display,
        DisplayCityLocation,
        DistanceSpacingEnabled,
        EditorTip,
        VideoEditor,
        EditorDefaultSkin,
        EditorSnakingSliders,
        EditorHitAnimations,
        EditorFollowPoints,
        EditorStacking,
        ForceSliderRendering,
        FpsCounter,
        FrameTimeDisplay,
        GuideTips,
        CursorRipple,
        HighlightWords,
        HighResolution,
        HitLighting,
        IgnoreBarline,
        IgnoreBeatmapSamples,
        IgnoreBeatmapSkins,
        IgnoreList,
        KeyOverlay,
        Language,
        LastPlayMode,
        AllowNowPlayingHighlights,
        LastVersion,
        LastVersionPermissionsFailed,
        LoadSubmittedThread,
        LobbyPlayMode,
        ShowInterface,
        ShowInterfaceDuringRelax,
        LobbyShowExistingOnly,
        LobbyShowFriendsOnly,
        LobbyShowFull,
        LobbyShowInProgress,
        LobbyShowPassworded,
        LogPrivateMessages,
        LowResolution,
        ManiaSpeed,
        UsePerBeatmapManiaSpeed,
        ManiaSpeedBPMScale,
        MenuTip,
        MouseDisableButtons,
        MouseDisableWheel,
        MouseSpeed,
        Offset,
        ScoreMeterScale,
        DistanceSpacing,
        EditorBeatDivisor,
        EditorGridSize,
        EditorGridSizeDesign,
        CustomFrameLimit,
        MsnIntegration,
        MyPcSucks,
        NotifyFriends,
        NotifySubmittedThread,
        PopupDuringGameplay,
        ProgressBarType,
        RankType,
        RefreshRate,
        OverrideRefreshRate,
        ScaleMode,
        ScoreboardVisible,
        ScoreMeter,
        ScreenshotId,
        MenuSnow,
        MenuTriangles,
        SongSelectThumbnails,
        ScreenshotFormat,
        ShowReplayComments,
        ShowSpectators,
        ShowStoryboard,
        Skin,
        SkinSamples,
        SkipTablet,
        SnakingInSliders,
        SnakingOutSliders,
        Tablet,
        UpdatePending,
        UserFilter,
        UseSkinCursor,
        UseTaikoSkin,
        Video,
        Wiimote,
        YahooIntegration,
        ForceFrameFlush,
        DetectPerformanceIssues,
        MenuMusic,
        MenuVoice,
        MenuParallax,
        RawInput,
        AbsoluteToOsuWindow,
        ConfineMouse,
        [Obsolete]
        ConfineMouseToFullscreen,
        ShowMenuTips,
        HiddenShowFirstApproach,
        ComboColourSliderBall,
        AlternativeChatFont,
        Username,
        DisplayStarsMaximum,
        DisplayStarsMinimum,
        AudioDevice,
        ReleaseStream,
        UpdateFailCount,
        SavePassword,
        SaveUsername,
        TreeSortMode,
        TreeSortMode2,
        ShowUnicode,
        PermanentSongInfo,
        Ticker,
        CompatibilityContext,
        CanForceOptimusCompatibility,

    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace CodeTorch.Designer.Code
{
    public interface ICodeTransformer
    {
        string EntityType { get; set; }
        XDocument Document { get; set; }
        List<string> GetSupportedEntityTypes();

        bool Execute();
    }
}


text:
A blog template using angular-seed, bootstrap and heroku.

1. Clone angular-seed
2. npm install bower --save
3. bower install angular angular-route bootstrap --save
4. npm install express --save
5. Create express server
6. Test server
7. Create Procfile
8. Copy bootstrap template into partial view
9. Copy custom css and link in index.html
10. Git add and commit
11. Heroku create and git push heroku master

After you get up and running, you can add and commit new changes, then push them to heroku with git push -f heroku master

http://salty-gorge-4623.herokuapp.com/


text:
#ifndef AXSpinButton_h
#define AXSpinButton_h

#include "core/html/shadow/SpinButtonElement.h"
#include "modules/accessibility/AXMockObject.h"

namespace blink {

class AXObjectCacheImpl;

class AXSpinButton final : public AXMockObject {
  WTF_MAKE_NONCOPYABLE(AXSpinButton);

 public:
  static AXSpinButton* create(AXObjectCacheImpl&);
  ~AXSpinButton() override;
  DECLARE_VIRTUAL_TRACE();

  void setSpinButtonElement(SpinButtonElement* spinButton) {
    m_spinButtonElement = spinButton;
  }
  void step(int amount);

 private:
  explicit AXSpinButton(AXObjectCacheImpl&);

  AccessibilityRole roleValue() const override;
  bool isSpinButton() const override { return true; }
  bool isNativeSpinButton() const override { return true; }
  void addChildren() override;
  LayoutObject* layoutObjectForRelativeBounds() const override;
  void detach() override;
  void detachFromParent() override;

  Member<SpinButtonElement> m_spinButtonElement;
};

class AXSpinButtonPart final : public AXMockObject {
 public:
  static AXSpinButtonPart* create(AXObjectCacheImpl&);
  ~AXSpinButtonPart() override {}
  void setIsIncrementor(bool value) { m_isIncrementor = value; }

 private:
  explicit AXSpinButtonPart(AXObjectCacheImpl&);
  bool m_isIncrementor : 1;

  bool press() const override;
  AccessibilityRole roleValue() const override { return ButtonRole; }
  bool isSpinButtonPart() const override { return true; }
  void getRelativeBounds(AXObject** outContainer,
                         FloatRect& outBoundsInContainer,
                         SkMatrix44& outContainerTransform) const override;
};

DEFINE_AX_OBJECT_TYPE_CASTS(AXSpinButton, isNativeSpinButton());
DEFINE_AX_OBJECT_TYPE_CASTS(AXSpinButtonPart, isSpinButtonPart());

}  // namespace blink

#endif  // AXSpinButton_h


text:
title: Thom Tillis, North Carolina Senator
name: Thom Tillis
avatar: /ui/img/avatars/Thom_Tillis.jpg
party: republican
state: north-carolina
type: senator
lasthall: 2012-01-29
phone: (202) 224-6342
never:
twitter: ThomTillis
---


text:
{% extends 'base.html' %}

{% block title %}{{ user.first_name }}{% endblock %}

{% block main %}

 {{ user.first_name }}

      {% if messages %}
        {% for message in messages %}

            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
            {{ message }}

        {% endfor %}
      {% endif %}

Change Password

      <form role="form" class="form-horizontal" method="post" action="{% url 'password' %}">
        {% csrf_token %}
        {{ form.id }}
        {% for field in form.visible_fields %}

            {{ field.label }}

              {{ field }}
              {% if field.help_text %}
                {{ field.help_text }}
              {% endif %}
              {% for error in field.errors %}
                {{ error }}
              {% endfor %}

        {% endfor %}

            <button type="submit" class="btn btn-primary">Save</button>

      </form>

{% endblock main %}


text:
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Mindscape.Raygun4Net.WinRT")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mindscape.Raygun4Net.WinRT")]
[assembly: AssemblyCopyright("Copyright ©  2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: ComVisible(false)]


text:
body { padding-top: 70px; }
#gesture-editor .time_for_gesture_test { width: 80px; text-align: right; }
.back-canvas { display: none;}
#bs-example-navbar-collapse-1 a.running{ background-color: #47a447; color: #fff;}
#bs-example-navbar-collapse-1 a.current_user { font-weight:bold }
.saved_gestures { float: left; margin-top: 8px; }
.save_gesture_input_container { float: left; margin-top: 3px;  margin-right: 10px; }
#new_user_profile { width: 158px; margin-left: 2px; margin-right: 2px; float: left; }
#user_dropdown { width: 140px; text-align: right; }


text:
<?php

namespace LengthOfRope\JSONLD\Schema;

/**
 * Enumerated for values for itemListOrder for indicating how an ordered ItemList is organized.
 *
 * @author LengthOfRope, Bas de Kort <bdekort@gmail.com>
 **/
class ItemListOrderTypeSchema extends EnumerationSchema
{
    public static function factory()
    {
        return new ItemListOrderTypeSchema('http://schema.org/', 'ItemListOrderType');
    }

}


text:
  Bouafles est
       un village
       localisé dans le département de l'Eure en Haute-Normandie. Elle comptait 630 habitants en 2008.

Si vous pensez emmenager à Bouafles, vous pourrez facilement trouver une maison à vendre.

La ville offre quelques  équipements sportifs, elle dispose, entre autres, de un centre d'équitation et un terrain de sport.

À Bouafles, le prix moyen à l'achat d'un appartement s'évalue à zero € du m² en vente. La valeur moyenne d'une maison à l'achat se situe à 1 656 € du m². À la location la valeur moyenne se situe à 7,56 € du m² mensuel.

Le nombre d'habitations, à Bouafles, était réparti en 2011 en sept appartements et 298 maisons soit
 un marché plutôt équilibré.

À coté de Bouafles sont localisées les communes de
Le Thuit à 5 km, 122 habitants,
Les Andelys à 4 km, 8 318 habitants,
Villers-sur-le-Roule située à 4 km, 660 habitants,
Noyers localisée à 5 km, 281 habitants,
Port-Mort située à 5 km, 1 008 habitants,
Tosny à 1 km, 610 habitants,
 entre autres. De plus, Bouafles est située à seulement 27 km de Évreux.


text:
package config

import (
	"fmt"
	"log"
	"os"

	"golang.org/x/crypto/ssh/terminal"
)

// ReadPassword reads a password without echoing it to the terminal.
func ReadPassword() string {
	line, err := terminal.ReadPassword(int(os.Stdin.Fd()))
	fmt.Fprintln(os.Stderr)
	if err != nil {
		log.Fatalf("Failed to read password: %v", err)
	}
	return string(line)
}


text:
This is derived from a quiz posted on rubyquiz.com see: http://rubyquiz.com/quiz6.html

## Problem Description

GEDCOM (http://en.wikipedia.org/wiki/GEDCOM) is the "GEnealogical Data COMmunication" file format. It is a plain-text electronic format used to transfer genealogical data. The purpose of this quiz is to develop a simple parser than can convert a GEDCOM file to an XML file.

The GEDCOM file format is very straightforward. Each line represents a node in a tree. It looks something like this:

      0 @I1@ INDI
      1 NAME Jamis Gordon /Buck/
      2 SURN Buck
      2 GIVN Jamis Gordon
      1 SEX M

In general, each line is formatted thus:

      LEVEL TAG-OR-ID [DATA]

The above sample would be rendered in XML as

    <gedcom>
      <indi id="@I1@">
        <name value="Jamis Gordon /Buck/">
          <surn>Buck</surn>
          <givn>Jamis Gordon</givn>
        </name>
        <sex>M</sex>
        ...
      </indi>
      ...
    </gedcom>

* "0 @I1@ INDI". This starts a new subtree of type INDI (individual). The id for this individual is "@I1@".
* "1 NAME Jamis Gordon /Buck/". This starts a NAME subtree with a value of "Jamis Gordon /Buck/".
* "2 SURN Buck". This is a subelement of the NAME subtree, of type SURN ("surname").
* "2 GIVN Jamis Gordon". As SURN, but specifies the given name of the individual.
* "1 SEX M". Creates a new subelement of the INDI element, of type "SEX" (i.e., "gender").

This is a simplified version of GEDCOM, the real spec is very broad and features many other elements and relationship types - produce a file format converter that isn't looking for specific tags.

### Story 1 - File format conversion

    As a user
    When I pass a block of GEDCOM data
    I can transcode it to XML


text:
package org.apache.lucene.util;

import org.apache.lucene.util.ByteBlockPool.Allocator;

/**
 * A {@link ByteBlockPool.Allocator} implementation that recycles unused byte
 * blocks in a buffer and reuses them in subsequent calls to
 * {@link #getByteBlock()}.
 * <p>
 * Note: This class is not thread-safe
 * </p>
 * @lucene.internal
 */
public final class RecyclingByteBlockAllocator extends ByteBlockPool.Allocator {
  private byte[][] freeByteBlocks;
  private final int maxBufferedBlocks;
  private int freeBlocks = 0;
  private final Counter bytesUsed;
  public static final int DEFAULT_BUFFERED_BLOCKS = 64;

  /**
   * Creates a new {@link RecyclingByteBlockAllocator}
   *
   * @param blockSize
   *          the block size in bytes
   * @param maxBufferedBlocks
   *          maximum number of buffered byte block
   * @param bytesUsed
   *          {@link Counter} reference counting internally allocated bytes
   */
  public RecyclingByteBlockAllocator(int blockSize, int maxBufferedBlocks,
      Counter bytesUsed) {
    super(blockSize);
    freeByteBlocks = new byte[maxBufferedBlocks][];
    this.maxBufferedBlocks = maxBufferedBlocks;
    this.bytesUsed = bytesUsed;
  }

  /**
   * Creates a new {@link RecyclingByteBlockAllocator}.
   *
   * @param blockSize
   *          the block size in bytes
   * @param maxBufferedBlocks
   *          maximum number of buffered byte block
   */
  public RecyclingByteBlockAllocator(int blockSize, int maxBufferedBlocks) {
    this(blockSize, maxBufferedBlocks, Counter.newCounter(false));
  }

  /**
   * Creates a new {@link RecyclingByteBlockAllocator} with a block size of
   * {@link ByteBlockPool#BYTE_BLOCK_SIZE}, upper buffered docs limit of
   * {@link #DEFAULT_BUFFERED_BLOCKS} ({@value #DEFAULT_BUFFERED_BLOCKS}).
   *
   */
  public RecyclingByteBlockAllocator() {
    this(ByteBlockPool.BYTE_BLOCK_SIZE, 64, Counter.newCounter(false));
  }

  @Override
  public byte[] getByteBlock() {
    if (freeBlocks == 0) {
      bytesUsed.addAndGet(blockSize);
      return new byte[blockSize];
    }
    final byte[] b = freeByteBlocks[--freeBlocks];
    freeByteBlocks[freeBlocks] = null;
    return b;
  }

  @Override
  public void recycleByteBlocks(byte[][] blocks, int start, int end) {
    final int numBlocks = Math.min(maxBufferedBlocks - freeBlocks, end - start);
    final int size = freeBlocks + numBlocks;
    if (size >= freeByteBlocks.length) {
      final byte[][] newBlocks = new byte[ArrayUtil.oversize(size,
          RamUsageEstimator.NUM_BYTES_OBJECT_REF)][];
      System.arraycopy(freeByteBlocks, 0, newBlocks, 0, freeBlocks);
      freeByteBlocks = newBlocks;
    }
    final int stop = start + numBlocks;
    for (int i = start; i < stop; i++) {
      freeByteBlocks[freeBlocks++] = blocks[i];
      blocks[i] = null;
    }
    for (int i = stop; i < end; i++) {
      blocks[i] = null;
    }
    bytesUsed.addAndGet(-(end - stop) * blockSize);
    assert bytesUsed.get() >= 0;
  }

  /**
   * @return the number of currently buffered blocks
   */
  public int numBufferedBlocks() {
    return freeBlocks;
  }

  /**
   * @return the number of bytes currently allocated by this {@link Allocator}
   */
  public long bytesUsed() {
    return bytesUsed.get();
  }

  /**
   * @return the maximum number of buffered byte blocks
   */
  public int maxBufferedBlocks() {
    return maxBufferedBlocks;
  }

  /**
   * Removes the given number of byte blocks from the buffer if possible.
   *
   * @param num
   *          the number of byte blocks to remove
   * @return the number of actually removed buffers
   */
  public int freeBlocks(int num) {
    assert num >= 0 : "free blocks must be >= 0 but was: "+ num;
    final int stop;
    final int count;
    if (num > freeBlocks) {
      stop = 0;
      count = freeBlocks;
    } else {
      stop = freeBlocks - num;
      count = num;
    }
    while (freeBlocks > stop) {
      freeByteBlocks[--freeBlocks] = null;
    }
    bytesUsed.addAndGet(-count*blockSize);
    assert bytesUsed.get() >= 0;
    return count;
  }
}


text:
'''
Manage Cloudwatch alarms

.. versionadded:: 2014.7.0

Create and destroy cloudwatch alarms. Be aware that this interacts with
Amazon's services, and so may incur charges.

This module uses boto, which can be installed via package, or pip.

This module accepts explicit credentials but can also utilize
IAM roles assigned to the instance through Instance Profiles. Dynamic
credentials are then automatically obtained from AWS API and no further
configuration is necessary. More Information available at:

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html

If IAM roles are not used you need to specify them either in a pillar or
in the minion's config file::

    cloudwatch.keyid: GKTADJGHEIQSXMKKRBJ08H
    cloudwatch.key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs

It's also possible to specify key, keyid and region via a profile, either
as a passed in dict, or as a string to pull from pillars or minion config:

.. code-block:: yaml

    myprofile:
      keyid: GKTADJGHEIQSXMKKRBJ08H
      key: askdjghsdfjkghWupUjasdflkdfklgjsdfjajkghs
      region: us-east-1

.. code-block:: yaml

    my test alarm:
      boto_cloudwatch_alarm.present:
        - name: my test alarm
        - attributes:
            metric: ApproximateNumberOfMessagesVisible
            namespace: AWS/SQS
            statistic: Average
            comparison: ">="
            threshold: 20000.0
            period: 60
            evaluation_periods: 1
            description: test alarm via salt
            dimensions:
              QueueName:
                - the-sqs-queue-name
            alarm_actions:
              - arn:aws:sns:us-east-1:1111111:myalerting-action
'''

# Import Python libs
from __future__ import absolute_import

# Import 3rd-party libs
import salt.ext.six as six

def __virtual__():
    '''
    Only load if boto is available.
    '''
    return 'boto_cloudwatch_alarm' if 'boto_cloudwatch.get_alarm' in __salt__ else False

def present(
        name,
        attributes,
        region=None,
        key=None,
        keyid=None,
        profile=None):
    '''
    Ensure the cloudwatch alarm exists.

    name
        Name of the alarm

    attributes
        A dict of key/value cloudwatch alarm attributes.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
    alarm_details = __salt__['boto_cloudwatch.get_alarm'](
        name, region, key, keyid, profile
    )

    # Convert to arn's
    for k in ["alarm_actions", "insufficient_data_actions", "ok_actions"]:
        if k in attributes:
            attributes[k] = __salt__['boto_cloudwatch.convert_to_arn'](
                attributes[k], region, key, keyid, profile
            )

    # Diff the alarm_details with the passed-in attributes, allowing for the
    # AWS type transformations
    difference = []
    if alarm_details:
        for k, v in six.iteritems(attributes):
            if k not in alarm_details:
                difference.append("{0}={1} (new)".format(k, v))
                continue
            v2 = alarm_details[k]
            if v == v2:
                continue
            if isinstance(v, six.string_types) and str(v) == str(v2):
                continue
            if isinstance(v, float) and v == float(v2):
                continue
            if isinstance(v, int) and v == int(v2):
                continue
            if isinstance(v, list) and sorted(v) == sorted(v2):
                continue
            difference.append("{0}='{1}' was: '{2}'".format(k, v, v2))
    else:
        difference.append("new alarm")
    create_or_update_alarm_args = {
        "name": name,
        "region": region,
        "key": key,
        "keyid": keyid,
        "profile": profile
    }
    create_or_update_alarm_args.update(attributes)
    if alarm_details:   # alarm is present.  update, or do nothing
        # check to see if attributes matches is_present. If so, do nothing.
        if len(difference) == 0:
            ret['comment'] = "alarm {0} present and matching".format(name)
            return ret
        if __opts__['test']:
            msg = 'alarm {0} is to be created/updated.'.format(name)
            ret['comment'] = msg
            ret['result'] = None
            return ret
        result = __salt__['boto_cloudwatch.create_or_update_alarm'](
            **create_or_update_alarm_args
        )
        if result:
            ret['changes']['diff'] = difference
        else:
            ret['result'] = False
            ret['comment'] = 'Failed to create {0} alarm'.format(name)
    else:  # alarm is absent. create it.
        if __opts__['test']:
            msg = 'alarm {0} is to be created/updated.'.format(name)
            ret['comment'] = msg
            ret['result'] = None
            return ret
        result = __salt__['boto_cloudwatch.create_or_update_alarm'](
            **create_or_update_alarm_args
        )
        if result:
            ret['changes']['new'] = attributes
        else:
            ret['result'] = False
            ret['comment'] = 'Failed to create {0} alarm'.format(name)
    return ret

def absent(
        name,
        region=None,
        key=None,
        keyid=None,
        profile=None):
    '''
    Ensure the named cloudwatch alarm is deleted.

    name
        Name of the alarm.

    region
        Region to connect to.

    key
        Secret key to be used.

    keyid
        Access key to be used.

    profile
        A dict with region, key and keyid, or a pillar key (string)
        that contains a dict with region, key and keyid.
    '''
    ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}

    is_present = __salt__['boto_cloudwatch.get_alarm'](name, region, key,
                                                       keyid, profile)

    if is_present:
        if __opts__['test']:
            ret['comment'] = 'alarm {0} is set to be removed.'.format(name)
            ret['result'] = None
            return ret
        deleted = __salt__['boto_cloudwatch.delete_alarm'](name, region, key,
                                                           keyid, profile)
        if deleted:
            ret['changes']['old'] = name
            ret['changes']['new'] = None
        else:
            ret['result'] = False
            ret['comment'] = 'Failed to delete {0} alarm.'.format(name)
    else:
        ret['comment'] = '{0} does not exist in {1}.'.format(name, region)

    return ret