class Dependabot::PullRequestUpdater::Azure

def azure_client_for_source

def azure_client_for_source
  @azure_client_for_source ||=
    T.let(
      Dependabot::Clients::Azure.for_source(
        source: source,
        credentials: credentials
      ),
      T.nilable(Dependabot::Clients::Azure)
    )
end

def commit_being_updated

def commit_being_updated
  @commit_being_updated ||=
    T.let(
      T.must(azure_client_for_source.commits(source_branch_name).first),
      T.nilable(T::Hash[String, T.untyped])
    )
end

def commit_message

def commit_message
  commit_being_updated.fetch("comment")
end

def create_temp_branch

def create_temp_branch
  author = author_details&.slice(:name, :email, :date)
  author = nil unless author&.any?
  response = azure_client_for_source.create_commit(
    temp_branch_name,
    base_commit,
    commit_message,
    files,
    author
  )
  JSON.parse(response.body).fetch("refUpdates").first.fetch("newObjectId")
end

def initialize(source:, files:, base_commit:, old_commit:,

def initialize(source:, files:, base_commit:, old_commit:,
               credentials:, pull_request_number:, author_details: nil)
  @source = source
  @files = files
  @base_commit = base_commit
  @old_commit = old_commit
  @credentials = credentials
  @pull_request_number = pull_request_number
  @author_details = author_details
end

def old_source_branch_commit

def old_source_branch_commit
  commit_being_updated.fetch("commitId")
end

def pull_request

def pull_request
  @pull_request ||=
    T.let(
      azure_client_for_source.pull_request(pull_request_number.to_s),
      T.nilable(T::Hash[String, T.untyped])
    )
end

def pull_request_exists?

def pull_request_exists?
  pull_request
  true
rescue Dependabot::Clients::Azure::NotFound
  false
end

def source_branch_exists?

def source_branch_exists?
  azure_client_for_source.branch(source_branch_name)
  true
rescue Dependabot::Clients::Azure::NotFound
  false
end

def source_branch_name

def source_branch_name
  @source_branch_name ||= T.let(
    pull_request&.fetch("sourceRefName")&.gsub("refs/heads/", ""),
    T.nilable(String)
  )
end

def temp_branch_name

def temp_branch_name
  @temp_branch_name ||=
    T.let(
      "#{source_branch_name}-temp-#{SecureRandom.uuid[0..6]}",
      T.nilable(String)
    )
end

def update

def update
  return unless pull_request_exists? && source_branch_exists?
  update_source_branch
end

def update_branch(branch_name, old_commit, new_commit)

def update_branch(branch_name, old_commit, new_commit)
  azure_client_for_source.update_ref(
    branch_name,
    old_commit,
    new_commit
  )
end

def update_source_branch

def update_source_branch
  # 1) Push the file changes to a newly created temporary branch (from base commit)
  new_commit = create_temp_branch
  # 2) Update PR source branch to point to the temp branch head commit.
  response = update_branch(source_branch_name, old_source_branch_commit, new_commit)
  # 3) Delete temp branch
  update_branch(temp_branch_name, new_commit, OBJECT_ID_FOR_BRANCH_DELETE)
  raise PullRequestUpdateFailed, response.fetch("customMessage", nil) unless response.fetch("success", false)
end