fastlane_version '2.71.0'

fastlane_require 'aws-sdk-s3'
fastlane_require 'erb'
fastlane_require 'json'
fastlane_require 'pathname'

skip_docs

configured = false
is_build_pr = false

# Executes before anything else use to setup the script
before_all do |lane, options|
  if lane.to_s == 'build_pr'
    pr = options[:pr]
    UI.success("Building #{pr}")
    ENV['BRANCH_TO_BUILD'] = pr
    is_build_pr = true
  end

  # Raises an error is git is not clean
  if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
    ensure_git_status_clean
  end

  # Block to ensure we are on the right branch
  branch = ENV['BRANCH_TO_BUILD'] || ENV['GIT_BRANCH']
  begin
    ensure_git_branch(
        branch: branch
    )
  rescue
    sh "git checkout #{branch}"
    UI.success("Using branch \"#{branch}\"")
  end

  # If we are going to commit changes to git create a separate branch
  # so no changes are done in the branch that is being built
  if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
    local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
    sh "git checkout -b #{local_branch}"
    UI.success("Creating branch \"#{local_branch}\"")
  end
end

after_all do |lane|
  if lane.to_s == 'build'
    submit_to_store
  end

  if ENV['RESET_GIT_BRANCH'] == 'true'
    branch = ENV['BRANCH_TO_BUILD'] || 'master'
    package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
    beta_dir = '../android/app/src/main/java/com/mattermost/rnbeta'
    release_dir = "../android/app/src/main/java/#{package_id.gsub '.', '/'}"

    if beta_dir != release_dir
      sh "rm -rf #{release_dir}"
    end

    reset_git_repo(
        force: true,
        skip_clean: true
    )
    sh "git checkout #{branch}"

    if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
      local_branch = ENV['GIT_LOCAL_BRANCH'] || 'build'
      sh "git branch -D #{local_branch}"
      UI.success("Deleted working branch \"#{local_branch}\"")
      if lane.to_s == 'build_pr'
        sh 'git checkout master'
        ## Remove the branch for the PR
        sh "git branch -D #{branch}"
        UI.success("Deleted PR branch \"#{branch}\"")
      end
    end
  end
end

desc 'Increment version number for both Android and iOS'
lane :set_app_version do
  version_number = ENV['VERSION_NUMBER']
  unless version_number.nil? || version_number.empty?
    package = load_config_json('../package.json')
    package['version'] = version_number
    save_config_json('../package.json', package)

    android_set_version_name(
        gradle_file: './android/app/build.gradle',
        version_name: version_number
    )

    increment_version_number(
        xcodeproj: './ios/Mattermost.xcodeproj',
        version_number: version_number
    )

    if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
      msg = ENV['INCREMENT_VERSION_NUMBER_MESSAGE'] || 'Bump app version number to '
      commit_message = "#{msg} #{version_number.to_s}"
      build_folder_path = Dir[File.expand_path('..')].first
      repo_path = (sh "git -C #{build_folder_path} rev-parse --show-toplevel").strip
      git_dirty_files = (sh "git -C #{repo_path} diff --name-only HEAD").split(" ").join(' ')

      unless git_dirty_files.empty?
        sh "git -C #{repo_path} commit -m \"#{commit_message}\" #{git_dirty_files}"
        UI.success("Successfully committed \"#{git_dirty_files}\" 💾.")
      end
    end
  end
end

desc 'Increments the build number for both Android and iOS'
lane :set_app_build_number do
  ## set the build number for both platforms
  # use the one for iOS if no env variable set
  if ENV['INCREMENT_BUILD_NUMBER'] === 'true'
    build_number = ENV['BUILD_NUMBER'] || (get_build_number(xcodeproj: './ios/Mattermost.xcodeproj').to_i + 1)
    increment_build_number(
        xcodeproj: './ios/Mattermost.xcodeproj',
        build_number: build_number
    )
    android_set_version_code(
        gradle_file: './android/app/build.gradle',
        version_code: build_number
    )


    if ENV['COMMIT_CHANGES_TO_GIT'] == 'true'
      msg = ENV['INCREMENT_BUILD_NUMBER_MESSAGE'] || 'Bump app build number to '
      commit_message = "#{msg} #{build_number.to_s}"
      build_folder_path = Dir[File.expand_path('..')].first
      repo_path = (sh "git -C #{build_folder_path} rev-parse --show-toplevel").strip
      git_dirty_files = (sh "git -C #{repo_path} diff --name-only HEAD").split(" ").join(' ')

      unless git_dirty_files.empty?
        sh "git -C #{repo_path} commit -m \"#{commit_message}\" #{git_dirty_files}"
        UI.success("Successfully committed \"#{git_dirty_files}\" 💾.")
      end
    end
  end
end

desc 'Configure the app before building'
lane :configure do
  json = load_config_json('../dist/assets/config.json')

  # Set the Segment API Key
  unless ENV['SEGMENT_API_KEY'].nil? || ENV['SEGMENT_API_KEY'].empty?
    json['SegmentApiKey'] =  ENV['SEGMENT_API_KEY']
  end

  # Configure Sentry if enabled
  if ENV['SENTRY_ENABLED'] == 'true'
    json['SentryEnabled'] = true
    json['SentryOrg'] = ENV['SENTRY_ORG']
    json['SentryProjectIos'] = ENV['SENTRY_PROJECT_IOS']
    json['SentryProjectAndroid'] = ENV['SENTRY_PROJECT_ANDROID']
    json['SentryDsnIos'] = ENV['SENTRY_DSN_IOS']
    json['SentryDsnAndroid'] = ENV['SENTRY_DSN_ANDROID']
  end

  # Save the config.json file
  save_config_json('../dist/assets/config.json', json)

  configured = true
end

desc 'Build the app for Android and iOS'
lane :build do |options|
  configure
  set_app_version
  set_app_build_number

  # Build the android app
  self.runner.current_platform = :android
  build

  # Build the ios app
  self.runner.current_platform = :ios
  build
end

desc 'Buid the app for Android and iOS unsigned'
lane :unsigned do
  configure

  # Build the android app
  self.runner.current_platform = :android
  unsigned

  # Build the ios app
  self.runner.current_platform = :ios
  unsigned
end

desc 'Build the app using a PR so QA can test'
lane :build_pr do
  configure

  # Build the android app
  self.runner.current_platform = :android
  build

  # Build the ios app
  self.runner.current_platform = :ios
  build
end

platform :ios do
  desc 'Build iOS app'
  lane :build do
    unless configured
      configure
    end
    update_identifiers
    replace_assets
    build_ios
    upload_file_to_s3({:os_type => "iOS"})
  end

  desc 'Build an unsigned ipa'
  lane :unsigned do
    unless configured
      configure
    end
    update_identifiers
    replace_assets
  end

  lane :update_identifiers do
    # Set the name for the app
    app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
    update_info_plist(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        display_name: app_name
    )

    # Set the notification service extension bundle identifier
    notification_bundle_id = ENV['NOTIFICATION_SERVICE_IDENTIFIER'] || 'com.mattermost.rnbeta.NotificationService'
    update_app_identifier(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'NotificationService/Info.plist',
        app_identifier: notification_bundle_id
    )

    find_replace_string(
        path_to_file: './ios/Mattermost.xcodeproj/project.pbxproj',
        old_string: 'com.mattermost.rnbeta.NotificationService',
        new_string: notification_bundle_id
    )

    # Set the share extension bundle identifier
    extension_bundle_id = ENV['EXTENSION_APP_IDENTIFIER'] || 'com.mattermost.rnbeta.MattermostShare'
    update_app_identifier(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'MattermostShare/Info.plist',
        app_identifier: extension_bundle_id
    )

    find_replace_string(
        path_to_file: './ios/Mattermost.xcodeproj/project.pbxproj',
        old_string: 'com.mattermost.rnbeta.MattermostShare',
        new_string: extension_bundle_id
    )

    # Set the app bundle id
    app_bundle_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
    update_app_identifier(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        app_identifier: app_bundle_id
    )

    find_replace_string(
        path_to_file: './ios/Mattermost.xcodeproj/project.pbxproj',
        old_string: 'com.mattermost.rnbeta',
        new_string: app_bundle_id
    )

    # If set update the development team
    unless ENV['FASTLANE_TEAM_ID'].nil? || ENV['FASTLANE_TEAM_ID'].empty?
    update_project_team(
        path: './ios/Mattermost.xcodeproj',
        teamid: ENV['FASTLANE_TEAM_ID']
    )
    end

    # Set the ICloud container
    icloud_container = ENV['IOS_ICLOUD_CONTAINER'] || 'iCloud.com.mattermost.rnbeta'
    update_icloud_container_identifiers(
        entitlements_file: './ios/Mattermost/Mattermost.entitlements',
        icloud_container_identifiers: [icloud_container]
    )

    # Set the app group id to share data between the app and the extension
    app_group_id = ENV['IOS_APP_GROUP'] || 'group.com.mattermost.rnbeta'
    update_app_group_identifiers(
        entitlements_file: './ios/Mattermost/Mattermost.entitlements',
        app_group_identifiers: [app_group_id]
    )

    find_replace_string(
        path_to_file: './ios/UploadAttachments/UploadAttachments/Constants.m',
        old_string: 'group.com.mattermost.rnbeta',
        new_string: app_group_id
    )


    update_app_group_identifiers(
        entitlements_file: './ios/MattermostShare/MattermostShare.entitlements',
        app_group_identifiers: [app_group_id]
    )

    update_app_group_identifiers(
        entitlements_file: './ios/NotificationService/NotificationService.entitlements',
        app_group_identifiers: [app_group_id]
    )

    # Sync the provisioning profiles using match
    if ENV['SYNC_PROVISIONING_PROFILES'] == 'true'
      match(type: ENV['MATCH_TYPE'] || 'adhoc')
    end
  end

  lane :replace_assets do
    if ENV['REPLACE_ASSETS'] == 'true'
      sh 'cp -R ../dist/assets/release/icons/ios/* ../ios/Mattermost/Images.xcassets/AppIcon.appiconset/'
      sh 'cp -R ../dist/assets/release/splash_screen/ios/* ../ios/SplashScreenResource/'
    end
  end

  error do |lane, exception|
    version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
    build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
    send_message_to_mattermost({
                                   :version_number => version,
                                   :build_number => build_number,
                                   :pretext => '',
                                   :title => 'Unsuccessful Build',
                                   :thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
                                   :msg => exception.message,
                                   :default_payloads => [:lane],
                                   :success => false
                               })
  end

  def build_ios()
    app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
    app_name_sub = app_name.gsub(" ", "_")
    config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug'
    method = ENV['IOS_BUILD_EXPORT_METHOD'].nil? || ENV['IOS_BUILD_EXPORT_METHOD'].empty? ? 'ad-hoc' : ENV['IOS_BUILD_EXPORT_METHOD']

    gym(
        clean: true,
        scheme: 'Mattermost',
        configuration: config_mode,
        workspace: './ios/Mattermost.xcworkspace',
        export_method: method,
        skip_profile_detection: true,
        output_name: "#{app_name_sub}.ipa",
        export_options: {
            signingStyle: 'manual',
            iCloudContainerEnvironment: 'Production'
        }
    )
  end

end

platform :android do
  desc 'Build Android app'
  lane :build do
    unless configured
      configure
    end
    configure_telemetry_android
    update_identifiers
    replace_assets
    link_sentry_android
    build_android
    move_apk_to_root
    upload_file_to_s3({:os_type => "Android"})
  end

  desc 'Build an unsigned apk'
  lane :unsigned do
    unless configured
      configure
    end
    update_identifiers
    replace_assets

    gradle(
        task: 'assemble',
        build_type: 'Unsigned',
        project_dir: 'android/'
    )
  end

  desc 'Update config and module/listener for Android telemetry'
  lane :configure_telemetry_android do
    if ENV['TELEMETRY_ENABLED'] == 'true' && ENV['TELEMETRY_URL'] != '' && ENV['TELEMETRY_API_KEY'] != ''
      # Update telemetry config
      json = load_config_json('../dist/assets/config.json')
      json['TelemetryEnabled'] = true
      json['TelemetryUrl'] = ENV['TELEMETRY_URL']
      json['TelemetryApiKey'] = ENV['TELEMETRY_API_KEY']
      save_config_json('../dist/assets/config.json', json)

      beta_dir = './android/app/src/main/java/com/mattermost/rnbeta/'

      # Listen to telemetry react markers
      find_replace_string(
          path_to_file: "#{beta_dir}MainApplication.java",
          old_string: '// addReactMarkerListener();',
          new_string: 'addReactMarkerListener();'
      )
    end
  end

  lane :update_identifiers do
    # Set the name for the app
    app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
    sh "echo '#{app_name}' > ../fastlane/metadata/android/en-US/title.txt"
    android_change_string_app_name(
        newName: app_name,
        stringsFile: './android/app/src/main/res/values/strings.xml'
    )

    package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
    android_change_package_identifier(newIdentifier: package_id, manifest: './android/app/src/main/AndroidManifest.xml')
    android_update_application_id(app_folder_name: 'android/app', application_id: package_id)

    beta_dir = './android/app/src/main/java/com/mattermost/rnbeta/'
    release_dir = "./android/app/src/main/java/#{package_id.gsub '.', '/'}/"
    if ENV['BUILD_FOR_RELEASE'] == 'true'
      find_replace_string(
          path_to_file: "#{beta_dir}MainApplication.java",
          old_string: 'return BuildConfig.DEBUG;',
          new_string: 'return false;'
      )
    end

    if release_dir != beta_dir
      unless Dir.exist?(".#{release_dir}")
        FileUtils.mkdir_p ".#{release_dir}"
      end

      sh "mv .#{beta_dir}* .#{release_dir}"

      find_replace_string(
          path_to_file: './android/app/BUCK',
          old_string: 'package com.mattermost.rnbeta;',
          new_string: "package #{package_id};"
      )

      Dir.glob(".#{release_dir}*.java") do |item|
        find_replace_string(
            path_to_file: item[1..-1],
            old_string: 'package com.mattermost.rnbeta;',
            new_string: "package #{package_id};"
        )
      end

      Dir.glob('../android/app/src/main/java/com/mattermost/share/*.java') do |item|
        find_replace_string(
            path_to_file: item[1..-1],
            old_string: 'import com.mattermost.rnbeta.MainApplication;',
            new_string: "import #{package_id}.MainApplication;"
        )
      end
    end
  end

  lane :replace_assets do
    if ENV['REPLACE_ASSETS'] == 'true'
      sh 'cp -R ../dist/assets/release/icons/android/* ../android/app/src/main/res/'
      sh 'cp -R ../dist/assets/release/splash_screen/android/* ../android/app/src/main/res/'
    end
  end

  error do |lane, exception|
    build_number = android_get_version_code(
        gradle_file: './android/app/build.gradle'
    )
    version_number = android_get_version_name(
        gradle_file: './android/app/build.gradle'
    )

   send_message_to_mattermost({
                                  :version_number => version_number,
                                  :build_number => build_number,
                                  :pretext => '',
                                  :title => 'Unsuccessful Build',
                                  :thumb_url => 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300',
                                  :msg =>  exception.message,
                                  :default_payloads => [:lane],
                                  :success => false,
                              })
  end

  def build_android()
    config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug'

    gradle(
        task: 'assemble',
        build_type: config_mode,
        project_dir: 'android/'
    )
  end

  def move_apk_to_root
    app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
    app_name_sub = app_name.gsub(" ", "_")
    new_apk_path = "#{Pathname.new(File.expand_path(File.dirname(__FILE__))).parent.to_s}/#{app_name_sub}.apk"
    apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]

    unless apk_path.nil?
      sh "mv #{apk_path} #{new_apk_path}"
      lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] = new_apk_path
    end
  end

  def link_sentry_android
    if ENV['SENTRY_ENABLED'] == 'true'
      url = 'https://sentry.io'
      File.open('../android/sentry.properties', 'w+') do |f|
        UI.message('Creating sentry.properties from environment')
        f.write(
            "defaults.url=#{url}\n"\
        "defaults.org=#{ENV['SENTRY_ORG']}\n"\
        "defaults.project=#{ENV['SENTRY_PROJECT_ANDROID']}\n"\
        "auth.token=#{ENV['SENTRY_AUTH_TOKEN']}\n"
        )
      end
    else
      UI.message('Not creating sentry.properties because Sentry is disabled')
    end
  end
end

def load_config_json(json_path)
  config_file = File.read(json_path)
  JSON.parse(config_file)
end

def save_config_json(json_path, json)
  File.open(json_path, 'w') do |f|
    f.write(JSON.pretty_generate(json))
  end
end

def send_message_to_mattermost(options)
  unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty?
    mattermost(
        pretext: options[:pretext],
        message: options[:msg],
        default_payloads: options[:default_payloads],
        username: 'Fastlane',
        icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
        payload: {},
        attachment_properties: {
            title: options[:title],
            thumb_url: options[:thumb_url],
            fields: [{
                         title: 'Version',
                         value: options[:version_number],
                         short: true
                     },
                     {
                         title: 'Build Number',
                         value: options[:build_number],
                         short: true
                     },
                     {
                         title: 'Built by',
                         value: 'Jenkins',
                         short: true
                     }]
        },
        success: options[:success]
    )
  end
end

def submit_to_store
  apk_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]
  ipa_path = lane_context[SharedValues::IPA_OUTPUT_PATH]

  app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
  app_name_sub = app_name.gsub(" ", "_")

  s3_region = ENV['AWS_REGION']
  s3_bucket = ENV['AWS_BUCKET_NAME']

  # Submit to Google Play if required
  if !apk_path.nil? && ENV['SUBMIT_ANDROID_TO_GOOGLE_PLAY'] == 'true'
    UI.success("apk file #{apk_path}")

    supply(
        track: ENV['SUPPLY_TRACK'] || 'alpha',
        apk: apk_path
    )

    version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
    build_number = android_get_version_code(gradle_file: './android/app/build.gradle')

    s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
    public_link = "https://#{s3_bucket}/#{s3_folder}/#{app_name_sub}.apk"

    # Send a build message to Mattermost
    pretext = '#### New Android released ready to be published'
    msg = "Release has been cut and is on the Beta track ready to be published.\nDownload link: #{public_link}"

    if ENV['BETA_BUILD'] == 'true'
      pretext = '#### New Android beta published to Google Play'
      msg = "Sign up as a beta tester [here](https://play.google.com/apps/testing/com.mattermost.rnbeta).\nDownload link: #{public_link}"
    end

    send_message_to_mattermost({
                                   :version_number => version_number,
                                   :build_number => build_number,
                                   :pretext => pretext,
                                   :title => '',
                                   :thumb_url => 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300',
                                   :msg => msg,
                                   :default_payloads => [],
                                   :success => true,
                               })
  end

  # Submit to TestFlight if required
  if !ipa_path.nil? && ENV['SUBMIT_IOS_TO_TESTFLIGHT'] == 'true'
    UI.success("ipa file #{ipa_path}")

    pilot

    version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
    build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')

    s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
    public_link = "https://#{s3_bucket}/#{s3_folder}/#{app_name_sub}.ipa"

    # Send a build message to Mattermost
    pretext = '#### New iOS released ready to be published'
    msg = "Release has been cut and is on TestFlight ready to be published.\nDownload link: #{public_link}"

    if ENV['BETA_BUILD'] == 'true'
      pretext = '#### New iOS beta published to TestFlight'
      msg = "Sign up as a beta tester [here](https://testflight.apple.com/join/Q7Rx7K9P).\nDownload link: #{public_link}"
    end

    send_message_to_mattermost({
                                   :version_number => version_number,
                                   :build_number => build_number,
                                   :pretext => pretext,
                                   :title => '',
                                   :thumb_url => 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png',
                                   :msg => msg,
                                   :default_payloads => [],
                                   :success => true,
                               })
  end
end

def qa_build_message(options)
  abbreviated_commit_hash = last_git_commit[:abbreviated_commit_hash]
  os_type = options[:os_type]
  install_url = options[:install_url]

  unless ENV['MATTERMOST_WEBHOOK_URL'].nil? || ENV['MATTERMOST_WEBHOOK_URL'].empty?
    os_type = options[:os_type]

    if os_type == 'Android'
      msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — [Android APK Link](#{install_url})"
      mattermost(message: msg, username: 'Fastlane', icon_url: 'https://lh3.ggpht.com/XL0CrI8skkxnboGct-duyg-bZ_MxJDTrjczyjdU8OP2PM1dmj7SP4jL1K8JQeMIB3AM=w300')
    elsif os_type == 'iOS'
      msg = "QA build [#{abbreviated_commit_hash}](https://github.com/mattermost/mattermost-mobile/commit/#{abbreviated_commit_hash}) — [iOS pList Link](#{install_url})"
      mattermost(message: msg, username: 'Fastlane', icon_url: 'https://support.apple.com/library/content/dam/edam/applecare/images/en_US/iOS/move-to-ios-icon.png')
    end
  else
    UI.success("PR Built for #{os_type}: #{install_url}")
  end
end

desc 'Upload file to s3'
lane :upload_file_to_s3 do |options|
  os_type = options[:os_type]
  file = options[:file]
  file_plist = ""

  if file.nil? || file.empty?
    app_name =  ENV['APP_NAME'] || 'Mattermost Beta'
    filename = app_name.gsub(" ", "_")

    if os_type == 'Android'
      file = "#{filename}.apk"
    elsif os_type == 'iOS'
      file = "#{filename}.ipa"
      file_plist = "#{filename}.plist"
    end
  end


  build_folder_path = Dir[File.expand_path('..')].first
  file_path = "#{build_folder_path}/#{file}"

  unless ENV['AWS_BUCKET_NAME'].nil? || ENV['AWS_BUCKET_NAME'].empty? || ENV['AWS_REGION'].nil? || ENV['AWS_REGION'].empty? || file_path.nil?
    s3_region = ENV['AWS_REGION']
    s3_bucket = ENV['AWS_BUCKET_NAME']
    s3_folder = ''

    if is_build_pr
      s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{ENV['BRANCH_TO_BUILD']}"
    else
      if os_type == 'Android'
        version_number = android_get_version_name(gradle_file: './android/app/build.gradle')
        build_number = android_get_version_code(gradle_file: './android/app/build.gradle')
      elsif os_type == 'iOS'
        version_number = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj', target: 'Mattermost')
        build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
      end

      s3_folder = "#{ENV['AWS_FOLDER_NAME']}/#{version_number}/#{build_number}"
    end

    s3 = Aws::S3::Resource.new(region: s3_region)
    file_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file}")
    file_obj.upload_file("#{file_path}")

    if is_build_pr
      if os_type == 'Android'
        install_url = "https://#{s3_bucket}/#{s3_folder}/#{file}"
      elsif os_type == 'iOS'
        current_build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
        plist_template = File.read('plist.erb')
        plist_body = ERB.new(plist_template).result(binding)

        plist_obj = s3.bucket(s3_bucket).object("#{s3_folder}/#{file_plist}")
        plist_obj.put(body: plist_body)

        install_url = "itms-services://?action=download-manifest&url=https://#{s3_bucket}/#{s3_folder}/#{file_plist}"
      end

      qa_build_message({
        :os_type => os_type,
        :install_url => install_url
      })
    end

    UI.success("S3 bucket @#{s3_bucket}, object @#{s3_folder}/#{file}")
    UI.success("S3 public path: https://#{s3_bucket}/#{s3_folder}/#{file}")
  end
end
