#ifndef FESA_APP_OUTPUT_PATHS_H_ #define FESA_APP_OUTPUT_PATHS_H_ #include #include #include #include #include "fesa/core/status.h" namespace fesa { /// @brief Names the input and user-addressed output files for one invocation. struct DerivedOutputPaths { std::filesystem::path input_path; std::filesystem::path results_path; std::filesystem::path log_path; }; /// @brief Retains exclusive ownership of one derived output pair. /// @note The lease owns a platform-private lock and must outlive output I/O. class OutputWriteLease { public: OutputWriteLease(const OutputWriteLease&) = delete; OutputWriteLease& operator=(const OutputWriteLease&) = delete; OutputWriteLease(OutputWriteLease&&) noexcept; OutputWriteLease& operator=(OutputWriteLease&&) noexcept; ~OutputWriteLease(); private: class Impl; friend Result AcquireOutputWriteLease( const DerivedOutputPaths& paths); explicit OutputWriteLease(std::unique_ptr impl) noexcept; std::unique_ptr impl_; }; /// @brief Validates CLI operands and derives lexical sibling output paths. /// @param arguments Arguments after argv[0]. /// @param invocation_cwd Lexical base for a relative input path. /// @return The input/result/log path triplet or a usage failure. /// @note This function does not resolve symlinks, junctions, or short names. Result DeriveSingleInputOutputPaths( const std::vector& arguments, const std::filesystem::path& invocation_cwd); /// @brief Acquires exclusive ownership for writes to one output pair. /// @return A move-only lease or an output-busy failure. /// @note The lease does not create, truncate, or replace public output files. Result AcquireOutputWriteLease( const DerivedOutputPaths& paths); } // namespace fesa #endif // FESA_APP_OUTPUT_PATHS_H_