using GisConverter.Lib.Models;
namespace GisConverter.Lib.Converters
{
///
/// Contract for a single converter implementation that knows how to transform a GIS input
/// artifact from one canonical format option to another.
///
///
///
/// Purpose
/// - Implementations of encapsulate the conversion logic required to
/// transform content from a detected or declared source format into a requested target format.
/// The interface is intentionally minimal so callers (CLI, services, tests) can invoke conversion
/// in a uniform, testable manner and consume a single describing
/// outcome and diagnostics.
///
///
///
/// Expected responsibilities of implementations
/// - Validate input paths and options early and return a descriptive failure result for predictable,
/// user-facing error conditions (missing files, unsupported format combinations, validation failures).
/// - Perform safe archive handling and extraction when the input is an archive; prefer streaming and bounded
/// reads for detection where possible. Use the library helpers in ConverterUtils for common behaviors
/// such as zip-slip protection and deterministic extraction.
/// - Write output artifacts into and use
/// for transient intermediate files. Document whether the implementation removes, renames or leaves temporaries.
/// - Return a that contains a concise, human-consumable message and an appropriate
/// ; include produced file paths or counts in informational results where helpful.
///
///
///
/// Error handling and diagnostics
/// - Prefer returning for known/expected failure modes (validation,
/// missing companion files, format-specific constraints). This keeps callers and tests deterministic.
/// - Catch unexpected exceptions at the converter boundary, log diagnostic details (via the host-provided logger)
/// and return a failure result rather than allowing exceptions to flow to top-level runners. Only let exceptions
/// escape when they represent unrecoverable framework-level failures that cannot be sensibly translated to a
/// user-facing message.
/// - ConversionResult.Message should be concise and suitable for presenting to users or for inclusion in CI failure
/// logs. If additional diagnostic data is necessary include it via structured logging (do not embed large stacks in
/// primary user messages).
///
///
///
/// Concurrency and thread-safety
/// - The interface is stateless. Implementations should avoid mutable static state so multiple converter instances
/// may be used concurrently. If a converter shares resources (for example static caches or drivers) it must
/// implement its own synchronization and document thread-safety guarantees.
/// - Converters should be safe to call from parallel test cases when per-invocation temporary folders are used.
///
///
///
/// Side-effects and cleanup conventions
/// - Converters may create files and directories under both and
/// . When possible:
/// - Create output files only under the supplied output folder.
/// - Use the supplied temp folder for extraction/intermediates and remove intermediate files on success.
/// - Wrap cleanup in best-effort try/catch so cleanup failures do not mask the conversion result; log cleanup failures.
/// - Document in your converter whether the temp folder is removed after success or retained for debugging. Tests often
/// assert that temp folders are cleaned up for successful conversions; make this behavior explicit.
///
///
///
/// Input types and detection
/// - Implementations should accept:
/// - Single-file inputs (CSV, GeoJSON, KML, etc.)
/// - Archive inputs (zip, kmz, 7z, etc.) where the converter may need to detect components inside the archive
/// (for example shapefile component files .shp/.shx/.dbf).
/// - When the converter depends on a detected source format, prefer the caller to pass the detected canonical
/// but be defensive if the option is null/ambiguous.
///
///
///
/// Testing expectations
/// - Tests that exercise converters call Convert and expect a rather than
/// process termination. Implementations MUST NOT call Environment.Exit or otherwise terminate the process.
/// - Provide deterministic outcomes for small, well-known sample inputs so unit/integration tests can assert using
/// stable tokens and file-presence checks.
///
///
///
/// Performance considerations
/// - Keep memory usage reasonable when processing large inputs; prefer streaming where possible (for example reading
/// and writing features incrementally rather than buffering whole collections in memory).
/// - Avoid long-running blocking operations on shared threads; if expensive work is required document expected execution
/// time and consider providing progress hooks at the host level.
///
///
///
/// Security and safety
/// - Treat untrusted input conservatively. When extracting archives validate entry names and paths (use zip-slip protections)
/// and do not write files outside the intended temp/output folders.
/// - Sanitize any file-based temporary names and limit resource creation to avoid denial-of-service risks in shared environments.
///
///
///
/// Localization & messaging
/// - Keep user-facing content language-agnostic where possible. Tests assert on
/// tokens (case-insensitive substrings) rather than exact messages to remain resilient to localization or wording updates.
///
///
///
/// Extension points
/// - Converters that require configuration or logging should accept those dependencies from the host (constructor injection)
/// rather than reaching into global state. This improves testability and avoids hidden global dependencies.
///
///
///
/// Example guidance for implementors
/// - Validate args:
/// - If is null/empty or the file does not exist return a failure result.
/// - Use helper utilities:
/// - Use ConverterUtils to extract archives safely and to build canonical output paths.
/// - Execute conversion:
/// - On success return with optional file path hints.
/// - On handled failure return with a helpful diagnostic message.
/// - On unexpected exceptions:
/// - Log the exception details and return a failure result rather than letting the exception escape.
///
///
public interface IConverter
{
///
/// Execute a conversion run.
///
/// Path to the input artifact. May be a single file or an archive.
/// Canonical source format option (e.g. "Shapefile").
/// Canonical target format option (e.g. "GeoJson").
/// Destination folder where output files should be written.
/// Temporary working folder for extraction and intermediates.
///
/// A describing success or failure. On success the result may
/// include informational text such as produced file paths; on failure it should include a
/// concise message suitable for user-facing diagnostics.
///
///
/// Implementations should validate inputs and return appropriate failure results for
/// missing/invalid arguments. The method must not call Environment.Exit or terminate
/// the process; it is expected to return a result so callers (including unit tests) can
/// assert on the outcome. If the converter requires additional configuration or logging it
/// should acquire those resources from the surrounding host rather than reaching into global
/// state.
///
ConversionResult Convert(
string gisInputFilePath,
string gisSourceFormatOption,
string gisTargetFormatOption,
string outputFolderPath,
string tempFolderPath);
}
}