flowmarkup:
  title: Storage Operations
  version: 1
  description: "File storage: S3 get/put, SFTP upload, cross-storage transfer, parseAs for JSON, RESOURCES upload."
  requires:
    STORAGE:
      s3_data:
        operations: [get, put, list, info, exists]
        paths: ["config/*", "data/*", "processed/*", "uploads/*"]
      backup_sftp: [put, mkdir]
    RESOURCES: [config_file]
    ENV: [TIMESTAMP]

  input:
    report_date:
      $kind: TEXT
      $format: '^\d{4}-\d{2}-\d{2}$'

  output:
    processed_count: INTEGER
    backup_path: TEXT

  vars:
    processed_count: 0

  do:

    # Upload a RESOURCES file to S3
  - storage:
      _label_: Upload config to S3
      url: s3_data
      operation: put
      path: ="uploads/" + meta(RESOURCES.config_file).name
      data: =RESOURCES.config_file
      timeout: 30s
      result:
        upload_path: =RESULT.path

    # Download JSON from S3 and auto-decode (alias form)
  - storage:
      _label_: Load settings from S3
      url: s3_data                     # bare alias (engine-provisioned)
      operation: get
      path: "config/settings.json"
      parseAs: JSON
      cacheHint: "5m"
      timeout: 30s
      result: { settings: =RESULT.data }

  - log: ="Loaded settings for region: " + settings.region

    # Check if a file exists before processing
  - storage:
      _label_: Check for daily export
      url: s3_data
      operation: exists
      path: ="data/export-" + report_date + ".csv"
      timeout: 10s
      result: { export_exists: =RESULT.exists }

  - if:
      condition: =export_exists
      then:
        # Download CSV, transform, re-upload
      - storage:
          _label_: Download daily export
          url: s3_data
          operation: get
          path: ="data/export-" + report_date + ".csv"
          parseAs: CSV
          timeout: 2m
          result: { events: =RESULT.data }

      - set:
          filtered: =events.filter(e, e.status == "active")
          processed_count: =size(filtered)

      - storage:
          _label_: Upload processed events
          url: s3_data
          operation: put
          path: ="processed/active-" + report_date + ".csv"
          data: =filtered
          timeout: 2m

    # Cache-aware file info check with full cache configuration
  - storage:
      _label_: Check export file metadata (cached)
      url: s3_data
      operation: info
      path: ="data/export-" + report_date + ".csv"
      cacheHint:
        ttl: 10m
        revalidation: CONDITIONAL
        scope: CONTEXT
        negative: true
        negativeTtl: 1m
        staleIfError: 30s
      timeout: 10s
      result: { export_info: =RESULT }

    # List files in a directory
  - storage:
      _label_: List recent data files
      url: s3_data
      operation: list
      path: "data/"
      limit: 50
      timeout: 30s
      result: { files: =RESULT.entries }

  - log: ="Found " + string(size(files)) + " files in data/"

    # Cross-storage transfer: S3 → SFTP (streamed)
  - storage:
      _label_: Backup to SFTP
      operation: transfer
      source:
        url: s3_data
        path: ="processed/active-" + report_date + ".csv"
      target:
        url: backup_sftp
        path: ="/backups/daily/" + report_date + ".csv"
      overwrite: true
      timeout: 30m
      result: { backup_path: =RESULT.targetPath }

  - log: ="Backup complete: " + backup_path

  - return: {processed_count: =processed_count, backup_path: =backup_path}
