﻿// Copyright 2020 Energinet DataHub A/S
//
// Licensed under the Apache License, Version 2.0 (the "License2");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System.Text.RegularExpressions;
using Energinet.DataHub.MeteringPoints.Domain.SeedWork;

namespace Energinet.DataHub.MeteringPoints.Domain.MasterDataHandling.Components.Addresses.Rules
{
    public class BuildingNumberFormatRule : IBusinessRule
    {
        private const int MaxLength = 6;
        private const string DanishFormat = @"^(?=.{1,4}$)((([1-9][0-9]{0,2})?[A-ZÆØÅ]*)|([A-ZÆØÅ]*([1-9][0-9]{0,2})?))$";

        public BuildingNumberFormatRule(string? buildingNumber, CountryCode? countryCode)
        {
            Validate(buildingNumber, countryCode);
        }

        public bool IsBroken { get; private set; }

        public ValidationError ValidationError { get; private set; } = new BuildingNumberFormatRuleError();

        private static bool IsDanish(CountryCode? countryCode)
        {
            if (countryCode is null)
            {
                return false;
            }

            return countryCode == CountryCode.DK;
        }

        private void Validate(string? buildingNumber, CountryCode? countryCode)
        {
            if (string.IsNullOrWhiteSpace(buildingNumber))
            {
                return;
            }

            if (IsDanish(countryCode))
            {
                ValidateDanishBuildingNumber(buildingNumber);
            }
            else
            {
                ValidateGeneralBuildingNumber(buildingNumber);
            }
        }

        private void ValidateDanishBuildingNumber(string buildingNumber)
        {
            if (Regex.IsMatch(buildingNumber!, DanishFormat) == false)
            {
                IsBroken = true;
                ValidationError = new BuildingNumberFormatRuleError(buildingNumber);
            }
        }

        private void ValidateGeneralBuildingNumber(string buildingNumber)
        {
            if (buildingNumber.Length > MaxLength)
            {
                IsBroken = true;
                ValidationError = new BuildingNumberFormatRuleError(buildingNumber);
            }
        }
    }
}
