/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied.
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 *
 * Author							Change						Date
 * ******************************************************************************
 * Mats Alm   		                Added       		        2011-01-01
 * Mats Alm                         Applying patch submitted    2011-11-14
 *                                  by Ted Heatherington
 * Jan Källman		                License changed GPL-->LGPL  2011-12-27
 * Raziq York		                Added support for Any type  2014-08-08
*******************************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Xml;
using OfficeOpenXml.DataValidation.Contracts;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml.DataValidation;

/// <summary>
/// <para>
/// Collection of <see cref="ExcelDataValidation"/>. This class is providing the API for EPPlus data validation.
/// </para>
/// <para>
/// The public methods of this class (Add[...]Validation) will create a datavalidation entry in the worksheet. When this
/// validation has been created changes to the properties will affect the workbook immediately.
/// </para>
/// <para>
/// Each type of validation has either a formula or a typed value/values, except for custom validation which has a formula only.
/// </para>
/// <code>
/// // Add a date time validation
/// var validation = worksheet.DataValidation.AddDateTimeValidation("A1");
/// // set validation properties
/// validation.ShowErrorMessage = true;
/// validation.ErrorTitle = "An invalid date was entered";
/// validation.Error = "The date must be between 2011-01-31 and 2011-12-31";
/// validation.Prompt = "Enter date here";
/// validation.Formula.Value = DateTime.Parse("2011-01-01");
/// validation.Formula2.Value = DateTime.Parse("2011-12-31");
/// validation.Operator = ExcelDataValidationOperator.between;
/// </code>
/// </summary>
public class ExcelDataValidationCollection : XmlHelper, IEnumerable<IExcelDataValidation> {
  private readonly List<IExcelDataValidation> _validations = new();
  private readonly ExcelWorksheet _worksheet;

  private const string _dataValidationPath = "//d:dataValidations";
  private readonly string DataValidationItemsPath = string.Format(
      "{0}/d:dataValidation",
      _dataValidationPath);

  protected override ImmutableArray<string> SchemaNodeOrder =>
    ExcelWorksheet.WorksheetSchemaNodeOrder;

  /// <summary>
  /// Constructor
  /// </summary>
  /// <param name="worksheet"></param>
  internal ExcelDataValidationCollection(ExcelWorksheet worksheet)
      : base(worksheet.NameSpaceManager, worksheet.WorksheetXml.DocumentElement) {
    Require.Argument(worksheet).IsNotNull("worksheet");
    _worksheet = worksheet;

    // check existing nodes and load them
    var dataValidationNodes = worksheet.WorksheetXml.SelectNodes(
        DataValidationItemsPath,
        worksheet.NameSpaceManager);
    if (dataValidationNodes != null && dataValidationNodes.Count > 0) {
      foreach (XmlNode node in dataValidationNodes) {
        if (node.Attributes["sqref"] == null) {
          continue;
        }

        var addr = node.Attributes["sqref"].Value;

        var typeSchema = node.Attributes["type"] != null ? node.Attributes["type"].Value : "";

        var type = ExcelDataValidationType.GetBySchemaName(typeSchema);
        _validations.Add(ExcelDataValidationFactory.Create(type, worksheet, addr, node));
      }
    }
  }

  private void EnsureRootElementExists() {
    var node = _worksheet.WorksheetXml.SelectSingleNode(
        _dataValidationPath,
        _worksheet.NameSpaceManager);
    if (node == null) {
      CreateNode(_dataValidationPath.TrimStart('/'));
    }
  }

  /// <summary>
  /// Validates address - not empty, collisions
  /// </summary>
  /// <param name="address"></param>
  /// <param name="validatingValidation"></param>
  private void ValidateAddress(string address, IExcelDataValidation validatingValidation) {
    Require.Argument(address).IsNotNullOrEmpty("address");

    // ensure that the new address does not collide with an existing validation.
    var newAddress = new ExcelAddress(address);
    if (_validations.Count > 0) {
      foreach (var validation in _validations) {
        if (validatingValidation != null && validatingValidation == validation) {
          continue;
        }
        var result = validation.Address.Collide(newAddress);
        if (result != ExcelAddressBase.eAddressCollition.No) {
          throw new InvalidOperationException(
              string.Format(
                  "The address ({0}) collides with an existing validation ({1})",
                  address,
                  validation.Address.Address));
        }
      }
    }
  }

  private void ValidateAddress(string address) {
    ValidateAddress(address, null);
  }

  /// <summary>
  /// Validates all data validations.
  /// </summary>
  internal void ValidateAll() {
    foreach (var validation in _validations) {
      validation.Validate();

      ValidateAddress(validation.Address.Address, validation);
    }
  }

  /// <summary>
  /// Adds a <see cref="ExcelDataValidationAny"/> to the worksheet.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationAny AddAnyValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationAny(_worksheet, address, ExcelDataValidationType.Any);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Adds an <see cref="IExcelDataValidationInt"/> to the worksheet. Whole means that the only accepted values
  /// are integer values.
  /// </summary>
  /// <param name="address">the range/address to validate</param>
  public IExcelDataValidationInt AddIntegerValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationInt(_worksheet, address, ExcelDataValidationType.Whole);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Addes an <see cref="IExcelDataValidationDecimal"/> to the worksheet. The only accepted values are
  /// decimal values.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationDecimal AddDecimalValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationDecimal(_worksheet, address, ExcelDataValidationType.Decimal);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Adds an <see cref="IExcelDataValidationList"/> to the worksheet. The accepted values are defined
  /// in a list.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationList AddListValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationList(_worksheet, address, ExcelDataValidationType.List);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Adds an <see cref="IExcelDataValidationInt"/> regarding text length to the worksheet.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationInt AddTextLengthValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationInt(_worksheet, address, ExcelDataValidationType.TextLength);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Adds an <see cref="IExcelDataValidationDateTime"/> to the worksheet.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationDateTime AddDateTimeValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationDateTime(
        _worksheet,
        address,
        ExcelDataValidationType.DateTime);
    _validations.Add(item);
    return item;
  }

  public IExcelDataValidationTime AddTimeValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationTime(_worksheet, address, ExcelDataValidationType.Time);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Adds a <see cref="ExcelDataValidationCustom"/> to the worksheet.
  /// </summary>
  /// <param name="address">The range/address to validate</param>
  /// <returns></returns>
  public IExcelDataValidationCustom AddCustomValidation(string address) {
    ValidateAddress(address);
    EnsureRootElementExists();
    var item = new ExcelDataValidationCustom(_worksheet, address, ExcelDataValidationType.Custom);
    _validations.Add(item);
    return item;
  }

  /// <summary>
  /// Removes an <see cref="ExcelDataValidation"/> from the collection.
  /// </summary>
  /// <param name="item">The item to remove</param>
  /// <returns>True if remove succeeds, otherwise false</returns>
  /// <exception cref="ArgumentNullException">if <paramref name="item"/> is null</exception>
  public bool Remove(IExcelDataValidation item) {
    if (!(item is ExcelDataValidation validation)) {
      throw new InvalidCastException(
          "The supplied item must inherit OfficeOpenXml.DataValidation.ExcelDataValidation");
    }
    Require.Argument(item).IsNotNull("item");
    TopNode.RemoveChild(validation.TopNode);
    return _validations.Remove(validation);
  }

  /// <summary>
  /// Number of validations
  /// </summary>
  public int Count => _validations.Count;

  /// <summary>
  /// Index operator, returns by 0-based index
  /// </summary>
  /// <param name="index"></param>
  /// <returns></returns>
  public IExcelDataValidation this[int index] {
    get => _validations[index];
    set => _validations[index] = value;
  }

  /// <summary>
  /// Index operator, returns a data validation which address partly or exactly matches the searched address.
  /// </summary>
  /// <param name="address">A cell address or range</param>
  /// <returns>A <see cref="ExcelDataValidation"/> or null if no match</returns>
  public IExcelDataValidation this[string address] {
    get {
      var searchedAddress = new ExcelAddress(address);
      return _validations.Find(x =>
          x.Address.Collide(searchedAddress) != ExcelAddressBase.eAddressCollition.No);
    }
  }

  /// <summary>
  /// Returns all validations that matches the supplied predicate <paramref name="match"/>.
  /// </summary>
  /// <param name="match">predicate to filter out matching validations</param>
  /// <returns></returns>
  public IEnumerable<IExcelDataValidation> FindAll(Predicate<IExcelDataValidation> match) {
    return _validations.FindAll(match);
  }

  /// <summary>
  /// Returns the first matching validation.
  /// </summary>
  /// <param name="match"></param>
  /// <returns></returns>
  public IExcelDataValidation Find(Predicate<IExcelDataValidation> match) {
    return _validations.Find(match);
  }

  /// <summary>
  /// Removes all validations from the collection.
  /// </summary>
  public void Clear() {
    DeleteAllNode(DataValidationItemsPath.TrimStart('/'));
    _validations.Clear();
  }

  /// <summary>
  /// Removes the validations that matches the predicate
  /// </summary>
  /// <param name="match"></param>
  public void RemoveAll(Predicate<IExcelDataValidation> match) {
    var matches = _validations.FindAll(match);
    foreach (var m in matches) {
      if (!(m is ExcelDataValidation validation)) {
        throw new InvalidCastException(
            "The supplied item must inherit OfficeOpenXml.DataValidation.ExcelDataValidation");
      }
      TopNode
          .SelectSingleNode(_dataValidationPath.TrimStart('/'), NameSpaceManager)
          .RemoveChild(validation.TopNode);
    }
    _validations.RemoveAll(match);
  }

  IEnumerator<IExcelDataValidation> IEnumerable<IExcelDataValidation>.GetEnumerator() {
    return _validations.GetEnumerator();
  }

  IEnumerator IEnumerable.GetEnumerator() {
    return _validations.GetEnumerator();
  }
}
