fastlane_version '2.56.0'
skip_docs

platform :ios do
  before_all do |lane|
    if lane == :beta or lane === :release
      current_branch = (sh 'git rev-parse --abbrev-ref HEAD').chop!

      UI.user_error!("To cut a beta or a release you need to be on master or in a release branch.
      Current branch is #{current_branch}
      Exiting") unless current_branch == 'master' or current_branch.start_with?('release')

      if lane == :beta
        sh "git checkout -b ios-#{lane}"
      end
    end
  end

  after_all do |lane|
    if lane == :beta
      reset_git_repo(
          force: true,
          skip_clean: true
      )

      sh 'git checkout master'
      sh "git branch -D ios-#{lane}"
    end
  end

  desc 'Build Release file'
  desc 'This will also make sure the profile is up to date'
  lane :dev do
    match(type: 'adhoc', app_identifier: 'com.mattermost.rnbeta')

    build_ios({
              release: false,
              increment_build: false,
              ensure_git_status_clean: false,
              method: 'ad-hoc'
          })
  end

  desc 'Submit a new Beta Build to Apple TestFlight'
  desc 'This will also make sure the profile is up to date'
  lane :beta do
    match(type: 'appstore', app_identifier: 'com.mattermost.rnbeta')

    configure_from_env()

    build_ios({
              release: true,
              increment_build: true,
              ensure_git_status_clean: true,
              method: 'app-store'
          })

    pilot(skip_waiting_for_build_processing: true)

    commit = last_git_commit

    push_to_git_remote(
        remote: 'origin',
        local_branch: 'ios-beta',
        force: false,
        tags: false
    )

    unless ENV['GITHUB_TOKEN'].nil?
      create_pull_request(
          api_token: ENV['GITHUB_TOKEN'],
          repo: 'mattermost/mattermost-mobile',
          head: 'mattermost:ios-beta',
          base: 'master',
          title: "IOS #{commit[:message]}"
      )
    end

    if ENV['MATTERMOST_WEBHOOK_URL']
      testflight_url = ENV['TESTFLIGHT_URL']
      send_message_for_ios(
          '#### New iOS beta published on TestFlight',
          '',
          "#ios-beta in #{testflight_url.nil? ? 'TestFlight' : "[TestFlight](#{testflight_url})"} on [#{Time.new.utc.to_s}]",
          [],
          true
      )
    end
  end

  desc 'Deploy a new version to the App Store'
  lane :release do
    match(type: 'appstore', app_identifier: 'com.mattermost.rn')

    configure_from_env()

    # snapshot

    update_app_identifier(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        app_identifier: 'com.mattermost.rn'
    )
    update_info_plist(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        display_name: 'Mattermost'
    )

    sh 'cp -R ../assets/release/icons/ios/* ../ios/Mattermost/Images.xcassets/AppIcon.appiconset/'

    build_ios({
              release: true,
              increment_build: false,
              ensure_git_status_clean: false,
              method: 'app-store'
          })

    # deliver(
    #     force: true,
    #     skip_screenshots: true,
    #     skip_metadata: true,
    #     submit_for_review: false, #lets try this after the first release
    #     automatic_release: false #lets try this after the first release
    # )

    ### We are going to publish the app to the testflight first and not deliver it directly to the app store
    pilot(skip_waiting_for_build_processing: true)

    # frameit

    reset_git_repo(
        force: true,
        skip_clean: true
    )

    if ENV['MATTERMOST_WEBHOOK_URL']
      appstore_url = ENV['APPSTORE_URL']
      send_message_for_ios(
          '#### New iOS release published on the App Store',
          '',
          "#ios-release in #{appstore_url.nil? ? 'App Store' : "[App Store](#{appstore_url})"} on [#{Time.new.utc.to_s}]",
          [],
          true
      )
    end
  end

  desc 'Build an unsigned ipa'
  lane :unsigned do
    if ENV['SEGMENT_API_KEY']
      find_replace_string(
          path_to_file: './dist/assets/config.json',
          old_string: '"SegmentApiKey": "3MT7rAoC0OP7yy3ThzqFSAtKzmzqtUPX"',
          new_string: "\"SegmentApiKey\": \"#{ENV['SEGMENT_API_KEY']}\""
      )
    end

    update_app_identifier(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        app_identifier: 'com.mattermost.rn'
    )
    update_info_plist(
        xcodeproj: './ios/Mattermost.xcodeproj',
        plist_path: 'Mattermost/Info.plist',
        display_name: 'Mattermost'
    )

    sh 'cp -R ../assets/release/icons/ios/* ../ios/Mattermost/Images.xcassets/AppIcon.appiconset/'
  end

  error do |lane, exception|
    if ENV['MATTERMOST_WEBHOOK_URL']
      send_message_for_ios('', 'Unsuccessful Build', exception.message, [:lane], false)
    end
  end

  def build_ios(options)
    if options[:ensure_git_status_clean]
      ensure_git_status_clean
    end

    if options[:increment_build]
      current_build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj').to_i
      increment_build_number(
          xcodeproj: './ios/Mattermost.xcodeproj',
          build_number: current_build_number + 1
      )
      commit_version_bump(xcodeproj: './ios/Mattermost.xcodeproj')
    end

    update_project_team(
        path: './ios/Mattermost.xcodeproj',
        teamid: ENV['FASTLANE_TEAM_ID']
    )

    gym(
        clean: true,
        scheme: 'Mattermost',
        configuration: (options[:release] ? 'Release' : 'Debug'),
        workspace: './ios/Mattermost.xcworkspace',
        export_method: options[:method]
    )
  end

  def send_message_for_ios(pretext, title, msg, default_payloads, success)
    version = get_version_number(xcodeproj: './ios/Mattermost.xcodeproj')
    build_number = get_build_number(xcodeproj: './ios/Mattermost.xcodeproj')
    mattermost(
        pretext: pretext,
        message: msg,
        default_payloads: default_payloads,
        username: 'Fastlane',
        icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
        payload: {},
        attachment_properties: {
            title: title,
            thumb_url: 'https://lh3.googleusercontent.com/Nkbo3QohCOU8bGqSYtwB88o03XxUwRAxRHNdXPB9zFvYFzTwD7naYa-GYJaelBp-OIc=w300',
            fields: [{
                         title: 'Version',
                         value: version,
                         short: true
                     },
                     {
                         title: 'Build Number',
                         value: build_number,
                         short: true
                     },
                     {
                         title: 'Built by',
                         value: 'Jenkins',
                         short: true
                     }]
        },
        success: success
    )
  end
end

platform :android do
  before_all do |lane|
    if lane == :alpha or lane === :release
      current_branch = (sh 'git rev-parse --abbrev-ref HEAD').chop!

      UI.user_error!("To cut a beta or a release you need to be on master or in a release branch.
      Current branch is #{current_branch}
      Exiting") unless current_branch == 'master' or current_branch.start_with?('release')

      if lane == :alpha
        sh "git checkout -b android-#{lane}"
      end
    end
  end

  after_all do |lane|
    if lane == :alpha
      reset_git_repo(
          force: true,
          skip_clean: true
      )
      sh 'git checkout master'
      sh "git branch -D android-#{lane}"
    end
  end

  desc 'Build Release file'
  lane :dev do
    build_android({release: true})
  end

  desc 'Submit a new Beta Build to Google Play'
  lane :alpha do
    configure_from_env()

    build_android({
                      release: true,
                      increment_build: true,
                      ensure_git_status_clean: true
                  })

    supply(
        track: 'alpha',
        apk: "#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}",
    )

    commit = last_git_commit

    push_to_git_remote(
        remote: 'origin',
        local_branch: 'android-alpha',
        force: false,
        tags: false
    )

    unless ENV['GITHUB_TOKEN'].nil?
      create_pull_request(
          api_token: ENV['GITHUB_TOKEN'],
          repo: 'mattermost/mattermost-mobile',
          head: 'mattermost:android-alpha',
          base: 'master',
          title: "Android #{commit[:message]}"
      )
    end

    if ENV['MATTERMOST_WEBHOOK_URL']
      beta_url = ENV['GOOGLE_PLAY_BETA_URL']
      send_message_for_android(
          '#### New Android beta published for Beta Testing',
          '',
          "#android-beta in #{beta_url.nil? ? 'Google Play Beta Program' : "[Google Play Beta Program](#{beta_url})"} on [#{Time.new.utc.to_s}]",
          [],
          true
      )
    end
  end

  desc 'Deploy a new version to Google Play'
  lane :release do
    prepare_release()

    build_android({
                      release: true,
                      increment_build: false,
                      ensure_git_status_clean: false
                  })

    supply(
        track: 'beta',
        apk: "#{lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH]}",
    )


    sh 'mv ../android/app/src/main/java/com/mattermost/rn/ ../android/app/src/main/java/com/mattermost/rnbeta/'

    reset_git_repo(
        force: true,
        skip_clean: true
    )

    if ENV['MATTERMOST_WEBHOOK_URL']
      google_play_url = ENV['GOOGLE_PLAY_URL']
      send_message_for_android(
          '#### New Android beta published for Production',
          '',
          "#android-beta in #{google_play_url.nil? ? 'Google Play' : "[Google Play](#{google_play_url})"} on [#{Time.new.utc.to_s}]",
          [],
          true
      )
    end
  end

  desc 'Build an unsigned apk'
  lane :unsigned do
    prepare_release()

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

  error do |lane, exception|
    if ENV['MATTERMOST_WEBHOOK_URL']
      send_message_for_android('', 'Unsuccessful Build', exception.message, [:lane], false)
    end
  end

  def prepare_release
    android_change_package_identifier(newIdentifier: 'com.mattermost.rn', manifest: './android/app/src/main/AndroidManifest.xml')
    android_change_string_app_name(newName: 'Mattermost', stringsFile: './android/app/src/main/res/values/strings.xml')
    android_update_application_id(app_folder_name: 'android/app', application_id: 'com.mattermost.rn')

    sh 'mv ../android/app/src/main/java/com/mattermost/rnbeta/ ../android/app/src/main/java/com/mattermost/rn/'
    sh 'cp -R ../assets/release/icons/android/* ../android/app/src/main/res/'

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/MainApplication.java',
        old_string: 'return BuildConfig.DEBUG;',
        new_string: 'return false;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/MainApplication.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/CustomPushNotification.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/MainActivity.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/NotificationsLifecycleFacade.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/NotificationDismissService.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/NotificationReplyService.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/NotificationPreferencesModule.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/NotificationPreferences.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/MattermostManagedModule.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/src/main/java/com/mattermost/rn/MattermostPackage.java',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './android/app/BUCK',
        old_string: 'package com.mattermost.rnbeta;',
        new_string: 'package com.mattermost.rn;'
    )

    find_replace_string(
        path_to_file: './fastlane/metadata/android/en-US/title.txt',
        old_string: 'Mattermost Beta',
        new_string: 'Mattermost'
    )

    configure_from_env()
  end

  def build_android(options)
    if options[:ensure_git_status_clean]
      ensure_git_status_clean
    end

    if options[:increment_build]
      android_increment_version_code(app_folder_name: 'android/app')
      android_commit_version_bump(
          app_folder_name: 'android/app',
          force: true
      )
    end

    link_sentry_android()

    gradle(
        task: 'assemble',
        build_type: (options[:release] ? 'Release' : 'Debug'),
        project_dir: 'android/'
    )
  end

  def get_version_code(app_folder_name)
    version_code = '0'

    Dir.glob("../#{app_folder_name}/build.gradle") do |path|
      begin
        UI.message(" -> Found a build.gradle file at path: (#{path})!")
        file = File.new(path, 'r')
        while (line = file.gets)
          if line.include? 'versionCode'
            versionComponents = line.strip.split(' ')
            version_code = versionComponents[1].tr("\"",'')
            break
          end
        end
        file.close
      rescue => err
        UI.error("An exception occured while reading gradle file: #{err}")
        err
      end
    end

    if version_code == '0'
      UI.user_error!("Impossible to find the version code in the current project folder #{app_folder_name} 😭")
    else
      # Store the version name in the shared hash
      Actions.lane_context['VERSION_CODE']=version_code
      UI.success("👍 Version name found: #{version_code}")
    end

    return version_code
  end

  def get_version_name(app_folder_name)
    version_name = '0'

    Dir.glob("../#{app_folder_name}/build.gradle") do |path|
      begin
        file = File.new(path, 'r')
        while (line = file.gets)
          if line.include? 'versionName'
            versionComponents = line.strip.split(' ')
            version_name = versionComponents[1].tr("\"",'')
            break
          end
        end
        file.close
      rescue => err
        UI.error("An exception occured while readinf gradle file: #{err}")
        err
      end
    end

    if version_name == '0'
      UI.user_error!("Impossible to find the version name in the current project folder #{app_folder_name} 😭")
    else
      # Store the version name in the shared hash
      Actions.lane_context['VERSION_NAME']=version_name
      UI.success("👍 Version name found: #{version_name}")
    end

    return version_name
  end

  def send_message_for_android(pretext, title, msg, default_payloads, success)
    build_number = get_version_code('android/app')
    version_name = get_version_name('android/app')
    mattermost(
        pretext: pretext,
        message: msg,
        default_payloads: default_payloads,
        username: 'Fastlane',
        icon_url: 'https://s3-eu-west-1.amazonaws.com/fastlane.tools/fastlane.png',
        payload: {},
        attachment_properties: {
            title: title,
            thumb_url: 'http://www.concretesolutions.com.br/blog/wp-content/uploads/2015/04/Android1.png',
            fields: [{
                         title: 'Version',
                         value: version_name,
                         short: true
                     },
                     {
                         title: 'Build Number',
                         value: build_number,
                         short: true
                     },
                     {
                         title: 'Built by',
                         value: 'Jenkins',
                         short: true
                     }]
        },
        success: success
    )
  end
end

def configure_from_env()
  if ENV['SEGMENT_API_KEY']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SegmentApiKey": "3MT7rAoC0OP7yy3ThzqFSAtKzmzqtUPX"',
        new_string: "\"SegmentApiKey\": \"#{ENV['SEGMENT_API_KEY']}\""
    )
  end

  if ENV['SENTRY_ENABLED']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryEnabled": false',
        new_string: "\"SentryEnabled\": #{ENV['SENTRY_ENABLED']}"
    )
  end

  if ENV['SENTRY_ORG']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryOrg": ""',
        new_string: "\"SentryOrg\": \"#{ENV['SENTRY_ORG']}\""
    )
  end

  if ENV['SENTRY_PROJECT_IOS']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryProjectIos": ""',
        new_string: "\"SentryProjectIos\": \"#{ENV['SENTRY_PROJECT_IOS']}\""
    )
  end

  if ENV['SENTRY_PROJECT_ANDROID']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryProjectAndroid": ""',
        new_string: "\"SentryProjectAndroid\": \"#{ENV['SENTRY_PROJECT_ANDROID']}\""
    )
  end

  if ENV['SENTRY_DSN_IOS']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryDsnIos": ""',
        new_string: "\"SentryDsnIos\": \"#{ENV['SENTRY_DSN_IOS']}\""
    )
  end

  if ENV['SENTRY_DSN_ANDROID']
    find_replace_string(
        path_to_file: './dist/assets/config.json',
        old_string: '"SentryDsnAndroid": ""',
        new_string: "\"SentryDsnAndroid\": \"#{ENV['SENTRY_DSN_ANDROID']}\""
    )
  end
end

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