// Copyright (C) Stichting Deltares 2019. All rights reserved.
//
// This file is part of Riskeer.
//
// Riskeer is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Components.Persistence.Stability;
using Core.Common.Base.Data;
using Core.Common.Base.IO;
using Core.Common.Util;
using log4net;
using Riskeer.Common.Data.Calculation;
using Riskeer.Common.Forms.Helpers;
using Riskeer.MacroStabilityInwards.Data;
using Riskeer.MacroStabilityInwards.IO.Properties;
using CoreCommonUtilResources = Core.Common.Util.Properties.Resources;
using CoreCommonGuiResources = Core.Common.Gui.Properties.Resources;
namespace Riskeer.MacroStabilityInwards.IO.Exporters
{
///
/// Exports macro stability inwards calculations from a calculation group and stores them as separate stix files.
///
public class MacroStabilityInwardsCalculationGroupExporter : IFileExporter
{
private static readonly ILog log = LogManager.GetLogger(typeof(MacroStabilityInwardsCalculationGroupExporter));
private readonly CalculationGroup calculationGroup;
private readonly IPersistenceFactory persistenceFactory;
private readonly string folderPath;
private readonly string fileExtension;
private readonly Func getNormativeAssessmentLevelFunc;
///
/// Creates a new instance of .
///
/// The calculation group to export.
/// The persistence factory to use.
/// The folder path to export to.
/// The extension of the files.
///
/// for obtaining the normative assessment level.
/// Thrown when ,
/// or is null.
/// Thrown when is invalid.
/// A valid path:
/// - is not empty or null,
/// - does not consist out of only whitespace characters,
/// - does not contain an invalid character,
/// - is not too long.
///
public MacroStabilityInwardsCalculationGroupExporter(CalculationGroup calculationGroup, IPersistenceFactory persistenceFactory, string folderPath,
string fileExtension, Func getNormativeAssessmentLevelFunc)
{
if (calculationGroup == null)
{
throw new ArgumentNullException(nameof(calculationGroup));
}
if (persistenceFactory == null)
{
throw new ArgumentNullException(nameof(persistenceFactory));
}
if (getNormativeAssessmentLevelFunc == null)
{
throw new ArgumentNullException(nameof(getNormativeAssessmentLevelFunc));
}
IOUtils.ValidateFolderPath(folderPath);
this.calculationGroup = calculationGroup;
this.persistenceFactory = persistenceFactory;
this.folderPath = folderPath;
this.fileExtension = fileExtension;
this.getNormativeAssessmentLevelFunc = getNormativeAssessmentLevelFunc;
}
public bool Export()
{
return ExportCalculationItemsRecursively(calculationGroup, folderPath);
}
private bool ExportCalculationItemsRecursively(CalculationGroup groupToExport, string currentFolderPath)
{
CreateDirectory(currentFolderPath);
var continueExport = true;
var exportedGroups = new List();
var exportedCalculations = new List();
foreach (ICalculationBase calculationItem in groupToExport.Children)
{
switch (calculationItem)
{
case CalculationGroup nestedGroup when HasChildrenWithOutput(nestedGroup):
continueExport = ExportCalculationGroup(nestedGroup, currentFolderPath, exportedGroups);
break;
case MacroStabilityInwardsCalculation calculation when !calculation.HasOutput:
log.WarnFormat(Resources.MacroStabilityInwardsCalculationGroupExporter_Export_Calculation_0_has_no_output_and_is_skipped, calculation.Name);
break;
case MacroStabilityInwardsCalculation calculation:
continueExport = ExportCalculation(calculation, currentFolderPath, exportedCalculations);
break;
}
if (!continueExport)
{
return false;
}
}
return true;
}
private static bool HasChildrenWithOutput(CalculationGroup nestedGroup)
{
MacroStabilityInwardsCalculation[] calculations = nestedGroup.Children.OfType()
.ToArray();
return calculations.Any() && calculations.All(calculation => calculation.HasOutput);
}
private static void CreateDirectory(string currentFolderPath)
{
if (!Directory.Exists(currentFolderPath))
{
Directory.CreateDirectory(currentFolderPath);
}
}
private bool ExportCalculationGroup(CalculationGroup nestedGroup, string currentFolderPath, ICollection exportedGroups)
{
string uniqueGroupName = NamingHelper.GetUniqueName(exportedGroups, nestedGroup.Name, group => group.Name);
bool exportSucceeded = ExportCalculationItemsRecursively(nestedGroup, Path.Combine(currentFolderPath, uniqueGroupName));
if (!exportSucceeded)
{
return false;
}
exportedGroups.Add(nestedGroup);
return true;
}
private bool ExportCalculation(MacroStabilityInwardsCalculation calculation, string currentFolderPath, ICollection exportedCalculations)
{
log.InfoFormat(CoreCommonGuiResources.GuiExportHandler_ExportItemUsingDialog_Start_exporting_DataType_0_, calculation.Name);
string filePath = GetCalculationFilePath(calculation, currentFolderPath, exportedCalculations);
var exporter = new MacroStabilityInwardsCalculationExporter(calculation, persistenceFactory, filePath, () => getNormativeAssessmentLevelFunc(calculation));
bool exportSucceeded = exporter.Export();
if (!exportSucceeded)
{
log.ErrorFormat("{0} {1}", string.Format(CoreCommonUtilResources.Error_General_output_error_0, filePath), Resources.MacroStabilityInwardsCalculationExporter_Export_no_stability_project_exported);
return false;
}
log.InfoFormat(Resources.MacroStabilityInwardsCalculationGroupExporter_Export_Data_from_0_exported_to_file_1, calculation.Name, filePath);
exportedCalculations.Add(calculation);
return true;
}
private string GetCalculationFilePath(ICalculationBase calculation, string currentFolderPath, IEnumerable exportedCalculations)
{
string uniqueName = NamingHelper.GetUniqueName(exportedCalculations, calculation.Name, c => c.Name);
string fileNameWithExtension = $"{uniqueName}.{fileExtension}";
return Path.Combine(currentFolderPath, fileNameWithExtension);
}
}
}