# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do
  desc "Push a new beta build to TestFlight"
  lane :beta do
    UI.message "Current working directory: #{Dir.pwd}"
    UI.message "Checking API key file..."
    
    possible_paths = [
      "../AuthKey.p8",
      "./AuthKey.p8", 
      "../../AuthKey.p8",
      File.expand_path("../AuthKey.p8"),
      File.expand_path("./AuthKey.p8")
    ]
    
    auth_key_path = nil
    possible_paths.each do |path|
      if File.exist?(path)
        UI.message "Found AuthKey.p8 at: #{path}"
        auth_key_path = File.expand_path(path)
        break
      end
    end
    
    if auth_key_path.nil?
      UI.user_error!("API key file not found. Tried paths: #{possible_paths.join(', ')}")
    end
    
    UI.message "Using auth_key_path: #{auth_key_path}"

    # Authenticate to App Store Connect early:
    # needed here by latest_testflight_build_number, not only by upload_to_testflight.
    app_store_connect_api_key(
      key_id: "325JS9JCZH",
      issuer_id: "dfa27d1d-2bb8-4d4d-847e-0b32f9b880b3",
      key_filepath: auth_key_path,
      duration: 1200,
      in_house: false
    )

    # Configure Flutter for release mode
    UI.message "Configuring Flutter for release mode..."
    sh("cd .. && flutter build ios --config-only --release")
    
    # Read version and build number from Flutter Generated.xcconfig.
    # They are only a floor: the actual build number is derived from TestFlight below,
    # so repeated CI runs on the same commit can never hit
    # ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE ("bundle version must be higher").
    generated_xcconfig_path = File.join("..", "Flutter", "Generated.xcconfig")
    flutter_build_name = nil
    flutter_build_number = nil

    if File.exist?(generated_xcconfig_path)
      File.foreach(generated_xcconfig_path) do |line|
        if (m = line.match(/FLUTTER_BUILD_NAME=(.*)/))
          flutter_build_name = m[1].strip
        elsif (m = line.match(/FLUTTER_BUILD_NUMBER=(.*)/))
          flutter_build_number = m[1].strip
        end
      end
    end

    if flutter_build_name.nil? || flutter_build_number.nil?
      UI.user_error!("Could not find FLUTTER_BUILD_NAME/FLUTTER_BUILD_NUMBER in #{generated_xcconfig_path}")
    end

    UI.message "Flutter version from pubspec: #{flutter_build_name} (#{flutter_build_number})"

    # Apple closes a version train once that version is approved/released.
    # Uploading into a closed train wastes a full ~8 min build and fails only
    # at the upload step with altool 90186 ("closed for new build submissions")
    # / 90062 ("must be higher than the previously approved version").
    # Fail fast here, before building.
    closed_train_states = [
      Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::READY_FOR_DISTRIBUTION,
      Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::PROCESSING_FOR_DISTRIBUTION,
      Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::PENDING_DEVELOPER_RELEASE,
      Spaceship::ConnectAPI::AppStoreVersion::AppVersionState::PENDING_APPLE_RELEASE
    ].join(",")
    asc_app = Spaceship::ConnectAPI::App.find("com.eatvioapp.app")
    closed_train = nil
    if asc_app.nil?
      UI.important("App com.eatvioapp.app not found in App Store Connect, skipping closed-train guard")
    else
      closed_train = asc_app.get_app_store_versions(
        filter: {
          appVersionState: closed_train_states,
          platform: Spaceship::ConnectAPI::Platform::IOS
        }
      ).find do |v|
        (Gem::Version.new(v.version_string) >= Gem::Version.new(flutter_build_name))
      rescue ArgumentError
        false
      end
    end
    if closed_train
      UI.user_error!(
        "Version train #{closed_train.version_string} is closed for new submissions " \
        "(#{closed_train.app_version_state}), pubspec version is #{flutter_build_name}. " \
        "Bump the version in pubspec.yaml above #{closed_train.version_string} and re-run."
      )
    end

    asc_latest_build_number = latest_testflight_build_number(
      app_identifier: "com.eatvioapp.app",
      version: flutter_build_name,
      initial_build_number: flutter_build_number.to_i
    )

    new_build_number = [flutter_build_number.to_i, asc_latest_build_number].max + 1
    UI.message "Latest TestFlight build number: #{asc_latest_build_number} -> uploading build #{new_build_number}"

    match(type: "appstore", readonly: true)

    # Set build number explicitly instead of incrementing
    increment_build_number(
      xcodeproj: "Runner.xcodeproj",
      build_number: new_build_number
    )

    update_code_signing_settings(
      use_automatic_signing: false,
      path: "Runner.xcodeproj",
      team_id: "VL68C36HYS",
      targets: ["Runner"],
      code_sign_identity: "Apple Distribution",
      profile_name: "match AppStore com.eatvioapp.app 1781098260"
    )
    
    build_app(
      workspace: "Runner.xcworkspace", 
      scheme: "Runner", 
      export_method: "app-store", 
      # codesigning_identity: "Apple Distribution",
      export_team_id: "VL68C36HYS"
    )

    begin
      upload_to_testflight(
        skip_waiting_for_build_processing: true,
        skip_submission: true,
        distribute_external: false,
        notify_external_testers: false,
        changelog: "TestFlight build #{new_build_number}",
        verbose: true
      )
    rescue => ex
      # Xcode 26 altool prints a harmless "ERROR: ... CDUploaderStateInfoResumeFilePath"
      # line even when the package was delivered fine (UPLOAD SUCCEEDED appears in the
      # same output). fastlane < 2.240.0 treats every ERROR line as a failure
      # (fastlane#30130), so the lane would die after a successful upload.
      # Real Apple rejections (90186 closed train, 90062 version too low, ...) always
      # contain UPLOAD FAILED and/or iris-code - those must still fail the lane.
      if ex.message.include?("CDUploaderStateInfoResumeFilePath") &&
         !ex.message.include?("UPLOAD FAILED") &&
         !ex.message.include?("iris-code")
        UI.important("altool delivered the package but reported a bogus resume-file ERROR " \
                     "(fastlane#30130). Treating upload as successful - " \
                     "verify the build appears in TestFlight.")
      else
        UI.error "Upload to TestFlight failed: #{ex.message}"
        UI.error "Full error: #{ex.backtrace.join("\n")}"
        raise ex
      end
    end
  end
end
