# 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
#

default_platform(:ios)

TEAMID = ENV["TEAMID"]
GH_PAT = ENV["GH_PAT"]
GITHUB_WORKSPACE = ENV["GITHUB_WORKSPACE"]
GITHUB_REPOSITORY_OWNER = ENV["GITHUB_REPOSITORY_OWNER"]
FASTLANE_KEY_ID = ENV["FASTLANE_KEY_ID"]
FASTLANE_ISSUER_ID = ENV["FASTLANE_ISSUER_ID"]
FASTLANE_KEY = ENV["FASTLANE_KEY"]
DEVICE_NAME = ENV["DEVICE_NAME"]
DEVICE_ID = ENV["DEVICE_ID"]
ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "120"


# Define method to parse xcconfig file, and replace $(DEVELOPMENT_TEAM) with ENV["TEAMID"]
def parse_xcconfig_file(path)
  xcconfig = {}
  File.open(path).each_line do |line|
    line.strip!
    next if line.empty? || line.start_with?('//')
    parts = line.split('=')
    next if parts.length < 2  # Skip lines without '='
    key, value = parts.map(&:strip)
    # Replace $(DEVELOPMENT_TEAM) with ENV["TEAMID"]
    value = value.gsub('$(DEVELOPMENT_TEAM)', TEAMID)
    xcconfig[key] = value
      end
      xcconfig
    end

# Path to config.xcconfig file
xcconfig_path = "#{GITHUB_WORKSPACE}/Config.xcconfig"

# Load the variables from config.xcconfig
xcconfig = parse_xcconfig_file(xcconfig_path)

# Access BUNDLE_IDENTIFIER from the xcconfig file after replacing $(DEVELOPMENT_TEAM) with ENV["TEAMID"]
ENV["BUNDLE_ID"] = xcconfig["BUNDLE_IDENTIFIER"]

# limit lane names to letters and underscores
platform :ios do
  desc "Build Trio"
  lane :build_trio do
    setup_ci if ENV['CI']
    BUNDLE_ID = ENV["BUNDLE_ID"]

    update_project_team(
      path: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      teamid: "#{TEAMID}"
    )

    api_key = app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )

    previous_build_number = latest_testflight_build_number(
      app_identifier: "#{BUNDLE_ID}",
      api_key: api_key,
    )

    current_build_number = previous_build_number + 1

    increment_build_number(
      xcodeproj: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      build_number: current_build_number
    )      
    
    match(
      type: "appstore",
      git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}"),
      app_identifier: [
        "#{BUNDLE_ID}",
        "#{BUNDLE_ID}.watchkitapp",
        "#{BUNDLE_ID}.watchkitapp.TrioWatchComplication",
        "#{BUNDLE_ID}.LiveActivity"

      ]
    )

    previous_build_number = latest_testflight_build_number(
      app_identifier: "#{BUNDLE_ID}",
      api_key: api_key,
    )

    current_build_number = previous_build_number + 1

    increment_build_number(
      xcodeproj: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      build_number: current_build_number
    )
    
    mapping = Actions.lane_context[
      SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING
    ]

    update_code_signing_settings(
      path: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      profile_name: mapping["#{BUNDLE_ID}"],
      code_sign_identity: "iPhone Distribution",
      targets: ["Trio"]
    )

    update_code_signing_settings(
      path: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      profile_name: mapping["#{BUNDLE_ID}.watchkitapp"],
      code_sign_identity: "iPhone Distribution",
      targets: ["Trio Watch App"]
    )

    update_code_signing_settings(
      path: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      profile_name: mapping["#{BUNDLE_ID}.watchkitapp.TrioWatchComplication"],
      code_sign_identity: "iPhone Distribution",
      targets: ["Trio Watch Complication Extension"]
    )

    update_code_signing_settings(
      path: "#{GITHUB_WORKSPACE}/Trio.xcodeproj",
      profile_name: mapping["#{BUNDLE_ID}.LiveActivity"],
      code_sign_identity: "iPhone Distribution",
      targets: ["LiveActivityExtension"]
    )

    gym(
      export_method: "app-store",
      scheme: "Trio",
      output_name: "Trio.ipa",
      configuration: "Release",
      destination: 'generic/platform=iOS',
      buildlog_path: 'buildlog'
    )

    copy_artifacts(
      target_path: "artifacts",
      artifacts: ["*.mobileprovision", "*.ipa", "*.dSYM.zip"]
    )
  end

  desc "Push to TestFlight"
  lane :release do
    api_key = app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )
    
    upload_to_testflight(
      api_key: api_key,
      skip_submission: false,
      ipa: "Trio.ipa",
      skip_waiting_for_build_processing: true,
      changelog: git_branch+" "+last_git_commit[:abbreviated_commit_hash],
    )
  end

  desc "Provision Identifiers and Certificates"
  lane :identifiers do
    setup_ci if ENV['CI']
    ENV["MATCH_READONLY"] = false.to_s
    BUNDLE_ID = ENV["BUNDLE_ID"]
    
    app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )

    def configure_bundle_id(name, identifier, capabilities)
      bundle_id = Spaceship::ConnectAPI::BundleId.find(identifier) || Spaceship::ConnectAPI::BundleId.create(
        name:       name,
        identifier: identifier,
        platform:   "IOS"
      )
      existing = bundle_id.get_capabilities.map(&:capability_type)
      capabilities.reject { |c| existing.include?(c) }.each do |cap|
        bundle_id.create_capability(cap)
      end
    end

    configure_bundle_id("Trio", "#{BUNDLE_ID}", [
      Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
      Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT,
      Spaceship::ConnectAPI::BundleIdCapability::Type::NFC_TAG_READING,
      Spaceship::ConnectAPI::BundleIdCapability::Type::PUSH_NOTIFICATIONS
    ])

    configure_bundle_id("Trio Watch Complication", "#{BUNDLE_ID}.watchkitapp.TrioWatchComplication", [
      Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS
    ])
    
    configure_bundle_id("Trio Watch App", "#{BUNDLE_ID}.watchkitapp", [
      Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
      Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT
    ])

    configure_bundle_id("Trio LiveActivity", "#{BUNDLE_ID}.LiveActivity", [])
    
  end

  desc "Provision Certificates"
  lane :certs do
    setup_ci if ENV['CI']
    ENV["MATCH_READONLY"] = false.to_s
    BUNDLE_ID = ENV["BUNDLE_ID"]
    
    app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )
    
    match(
      type: "appstore",
      force: false,
      verbose: true,
      git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}"),
      app_identifier: [
        "#{BUNDLE_ID}",
        "#{BUNDLE_ID}.watchkitapp",
        "#{BUNDLE_ID}.watchkitapp.TrioWatchComplication",
        "#{BUNDLE_ID}.LiveActivity"
      ]
    )
  end

  desc "Validate Secrets"
  lane :validate_secrets do
    setup_ci if ENV['CI']
    ENV["MATCH_READONLY"] = true.to_s
    BUNDLE_ID = ENV["BUNDLE_ID"]

    app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )

    def find_bundle_id(identifier)
      bundle_id = Spaceship::ConnectAPI::BundleId.find(identifier)
    end

    find_bundle_id("#{BUNDLE_ID}")

    match(
      type: "appstore",
      git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}"),
      app_identifier: [],
    )
  end

  desc "Nuke Certs"
  lane :nuke_certs do
    setup_ci if ENV['CI']
    ENV["MATCH_READONLY"] = false.to_s
    
    app_store_connect_api_key(
      key_id: "#{FASTLANE_KEY_ID}",
      issuer_id: "#{FASTLANE_ISSUER_ID}",
      key_content: "#{FASTLANE_KEY}"
    )
    
    match_nuke(
      type: "appstore",
      team_id: "#{TEAMID}",
      skip_confirmation: true,
      git_basic_authorization: Base64.strict_encode64("#{GITHUB_REPOSITORY_OWNER}:#{GH_PAT}")
    )
  end

  desc "Check Certificates and Trigger Workflow for Expired or Missing Certificates"
  lane :check_and_renew_certificates do
    setup_ci if ENV['CI']
    ENV["MATCH_READONLY"] = false.to_s
  
    # Authenticate using App Store Connect API Key
    api_key = app_store_connect_api_key(
      key_id: ENV["FASTLANE_KEY_ID"],
      issuer_id: ENV["FASTLANE_ISSUER_ID"],
      key_content: ENV["FASTLANE_KEY"] # Ensure valid key content
    )
  
    # Initialize flag to track if renewal of certificates is needed
    new_certificate_needed = false
  
    # Fetch all certificates
    certificates = Spaceship::ConnectAPI::Certificate.all
  
    # Filter for Distribution Certificates
    distribution_certs = certificates.select { |cert| cert.certificate_type == "DISTRIBUTION" }
  
    # Handle case where no distribution certificates are found
    if distribution_certs.empty?
      puts "No Distribution certificates found! Triggering action to create certificate."
      new_certificate_needed = true
    else
      # Check for expiration
      distribution_certs.each do |cert|
        expiration_date = Time.parse(cert.expiration_date)
  
        puts "Current Distribution Certificate: #{cert.id}, Expiration date: #{expiration_date}"
  
        if expiration_date < Time.now
          puts "Distribution Certificate #{cert.id} is expired! Triggering action to renew certificate."
          new_certificate_needed = true
        else
          puts "Distribution certificate #{cert.id} is valid. No action required."
        end
      end
    end
  
    # Write result to new_certificate_needed.txt
    file_path = File.expand_path('new_certificate_needed.txt')
    File.write(file_path, new_certificate_needed ? 'true' : 'false')  
  
    # Log the absolute path and contents of the new_certificate_needed.txt file
    puts ""
    puts "Absolute path of new_certificate_needed.txt: #{file_path}"
    new_certificate_needed_content = File.read(file_path)
    puts "Certificate creation or renewal needed: #{new_certificate_needed_content}"
  end
end