using qdr.app.tools.qfu.Commands.Aspects; using Quadarax.Foundation.Core.QConsole; using Quadarax.Foundation.Core.QConsole.Argument; using Quadarax.Foundation.Core.QConsole.Attributes; using Quadarax.Foundation.Core.Value; namespace qdr.app.tools.qfu.Commands { [CommandDefinition] internal class CloneCmd : BaseCmd { #region *** Constants *** private const string CMD_NAME = "clone"; private const string CMD_DESCR = "Clone source file to files specified."; private const string ARG_N_NAME = "n"; private const string ARG_N_HINT = "ncount"; private const string ARG_N_DESCR = "Numeric value how many <{0}> files will be generated. If used, then files in <{1}> arguments will be ignored."; #endregion #region *** Properties *** public override string Name => CMD_NAME; public override string Description => CMD_DESCR; protected string[] TargetFiles { get; private set; } = Array.Empty(); protected bool IsEnsurePath { get; private set; } = false; protected bool IsForce { get; private set; } = false; protected int? CloneCount{ get; private set; } #endregion #region *** Constructors *** public CloneCmd(Engine engine) : base(engine) { } #endregion #region *** Overrides *** #region **** EXECUTE **** protected override Result OnExecute() { WriteCaption($"Will be clonig file '{Source}' to {TargetFiles.Length} files {(IsForce ? "(with force)": string.Empty)}... "); var cnt = 0; var succ = 0; var bSucc = true; foreach (var file in TargetFiles) { cnt++; if (FileSystem.File.Exists(file) && !IsEnsurePath) { if (!IsForce) { WriteWarning($"[{cnt}] File '{file}' already exists. Skipping clone operation."); continue; } } try { FileSystem.File.Copy(Source, file, true); if (FileSystem.File.Exists(file)) succ++; else WriteWarning($"[{cnt}] File '{file}' does not exist after copy operation."); WriteInfo($"[{cnt}] Cloned '{Source}' to '{file}' successfully."); } catch (Exception ex) { WriteError($"[{cnt}] Failed to clone '{Source}' to '{file}': {ex.Message}"); bSucc = false; } } WriteCaption($"Succesfully cloned: {succ} of {cnt} files."); bSucc = succ == cnt; return bSucc ? new Result() : new Result(new Exception($"Failed to clone {TargetFiles.Length - succ} files from '{Source}'.")); } #endregion #region **** Arguments **** protected override void OnValidateArguments() { if(WasArgumentSpecified(ARG_N_NAME)) { // count argument is set -> fake argument to ensure that files are not used var argTaget = GetArgument(FilesAspect.ARG_FILES_NAME); argTaget.Value.Set("file"); } base.OnValidateArguments(); CheckSourceFileExists(); if(WasArgumentSpecified(ARG_N_NAME)) { CloneCount = GetArgumentValueOrDefault(ARG_N_NAME, 0); TargetFiles = GenerateTargetFiles(CloneCount.Value); } else TargetFiles = ListAspect.GetFiles(this, FileSystem, FilesAspect.GetFiles(this, FileSystem, false)); IsEnsurePath = GetArgumentValueOrDefault(FilesAspect.ARG_PATHENS_NAME, false); IsForce = GetArgumentValueOrDefault(ForceAspect.ARG_FORCE_NAME, false); } protected override IEnumerable OnSetupArguments() { var list = base.OnSetupArguments().ToList(); list.Add(new NamedArgument(ARG_N_NAME, string.Format(ARG_N_DESCR, SourceAspect.ARG_SRC_NAME, FilesAspect.ARG_FILES_NAME), ARG_N_HINT,Quadarax.Foundation.Core.QConsole.Value.TypeValuesEnum.Integer, "0",false)); list.AddRange(ListAspect.SetupArguments()); list.AddRange(FilesAspect.SetupArguments()); list.AddRange(ForceAspect.SetupArguments()); return list; } #endregion #region **** Private Operations **** private string[] GenerateTargetFiles(int count) { if (count <= 0) throw new ArgumentException("Count must be greater than zero.", nameof(count)); var fileName = Path.GetFileNameWithoutExtension(Source); var fileExt = Path.GetExtension(Source); var directory = Path.GetDirectoryName(Source) ?? string.Empty; var files = new string[count]; for (int i = 0; i < count; i++) { files[i] = Path.Combine(directory, $"{fileName}_{i + 1}{fileExt}"); } return files; } #endregion #endregion } }