# frozen_string_literal: true

#
# Copyright (C) 2012 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

require_relative "../common"

module FilesCommon
  # This method adds the specified file to the course
  # Params:
  # - fixture: location of the file to be uploaded
  # - context: course in which file would be uploaded
  # - name: file name
  # - folder: course folder it should go under (defaults to root folder)
  def add_file(fixture, context, name, folder = Folder.root_folders(context).first)
    context.attachments.create! do |attachment|
      attachment.uploaded_data = fixture
      attachment.filename = name
      attachment.folder = folder
    end
  end

  def edit_name_from_cog_icon(file_name_new, row_selected = 0)
    ff(".al-trigger-gray")[row_selected].click
    fln("Rename").click
    expect(f(".ef-edit-name-cancel")).to be_displayed
    file_name_textbox_el = f(".ef-edit-name-form__input")
    replace_content(file_name_textbox_el, file_name_new)
    file_name_textbox_el.send_keys(:return)
  end

  def delete_file(row_selected = 0, delete_using = :cog_icon)
    case delete_using
    when :cog_icon
      ff(".al-trigger")[row_selected].click
      fln("Delete").click
    when :toolbar_menu
      ff(".ef-item-row")[row_selected].click
      f(".btn-delete").click
    end
    confirm_delete_on_dialog
  end

  def move(file_name, row_selected = 0, move_using = :cog_icon, destination = nil)
    case move_using
    when :cog_icon
      ff(".al-trigger")[row_selected].click
      fln("Move To...").click
    when :toolbar_menu
      ff(".ef-item-row")[row_selected].click
      f(".btn-move").click
    end
    expect(f(".ReactModal__Header-Title h4")).to include_text "Where would you like to move #{file_name}?"
    if destination.present?
      folders = destination.split("/")
      folders.each do |folder|
        fj(".ReactModal__Body .treeLabel span:contains('#{folder}')").click
      end
    else
      ff(".treeLabel span")[3].click
    end
    driver.action.send_keys(:return).perform
    wait_for_ajaximations
    ff(".btn-primary")[1].click
  end

  def move_multiple_using_toolbar(files = [])
    files.each do |file_name|
      file = driver.find_element(xpath: "//span[contains(text(), '#{file_name}') and @class='ef-name-col__text']")
                   .find_element(xpath: "../..")
      driver.action.key_down(:command).click(file).key_up(:command).perform
    end
    wait_for_ajaximations
    f(".btn-move").click
    wait_for_ajaximations
    expect(f(".ReactModal__Header-Title h4").text).to eq "Where would you like to move these #{files.count} items?"
    ff(".treeLabel span")[3].click
    driver.action.send_keys(:return).perform
    wait_for_ajaximations
    ff(".btn-primary")[1].click
  end

  # This method sets permissions on files/folders
  def set_item_permissions(permission_type = :publish, restricted_access_option = nil, set_permissions_from = :cloud_icon)
    case set_permissions_from
    when :cloud_icon
      f(".btn-link.published-status").click
    when :toolbar_menu
      ff(".ef-item-row")[0].click
      f(".btn-restrict").click
    end
    wait_for_ajaximations
    if permission_type == :publish
      driver.find_elements(:name, "permissions")[0].click
    elsif permission_type == :unpublish
      driver.find_elements(:name, "permissions")[1].click
    elsif restricted_access_option == :available_with_link
      driver.find_elements(:name, "permissions")[2].click
    else
      driver.find_elements(:name, "permissions")[3].click
      ff(".ui-datepicker-trigger.btn")[0].click
      fln("15").click
      ff(".ui-datepicker-trigger.btn")[0].send_keys(:enter) # close the calendar
      wait_for_ajaximations
      driver.find_element(id: "timeSelectInput").send_keys("6:00 AM")
      ff(".ui-datepicker-trigger.btn")[1].click
      fln("25").click
      ff(".ui-datepicker-trigger.btn")[1].send_keys(:enter) # close the calendar
      driver.find_element(id: "lockDateTime").send_keys("11:59 PM")
    end
    ff(".btn.btn-primary")[1].click
    wait_for_ajaximations
  end

  def should_make_folders_in_the_menu_droppable
    course_with_teacher_logged_in
    get "/files"
    wait_for_ajaximations
    f(".add_folder_link").click
    wait_for_ajaximations
    expect(f("#files_content .add_folder_form #folder_name")).to be_displayed
    f("#files_content .add_folder_form #folder_name").send_keys("my folder\n")
    wait_for_ajaximations
    expect(f(".node.folder span")).to have_class("ui-droppable")

    # also make sure that it has a tooltip of the file name so that you can read really long names
    expect(f(".node.folder .name[title='my folder']")).not_to be_nil
  end

  def should_show_students_link_to_download_zip_of_folder
    course_with_student_logged_in
    get "/courses/#{@course.id}/files"
    link = f(".links a.download_zip_link")
    wait_for_ajaximations
    expect(link).to be_displayed
    expect(link).to have_attribute("href", %r{/courses/#{@course.id}/folders/\d+/download})
  end

  def confirm_delete_on_dialog
    driver.switch_to.alert.accept
    wait_for_ajaximations
  end

  def cancel_delete_on_dialog
    driver.switch_to.alert.dismiss
    wait_for_ajaximations
  end

  def add_folder(name = "new folder")
    click_new_folder_button
    new_folder = f("input[aria-label='Folder Name']")
    new_folder.click # sometimes send_keys won't send all keys unless click first
    new_folder.send_keys(name)
    f(".ef-edit-name-accept").click
    wait_for_ajaximations
  end

  def click_new_folder_button
    f("button[aria-label='Add Folder']").click
    wait_for_ajaximations
  end

  def create_new_folder
    f(".btn-add-folder").click
    f("input[aria-label='Folder Name']").send_keys(:return)
    wait_for_ajaximations
    all_files_folders.first
  end

  def all_files_folders
    # TODO: switch to ff once specs stop using this to find non-existence of stuff
    driver.find_elements(:class, "ef-item-row")
  end

  def insert_file_from_rce(insert_into = nil, filename = nil)
    fj('[role=tablist] [role=presentation]:not([aria-disabled]):contains("Files")').click
    fj('[role=tabpanel] button:contains("unfiled")').click
    fj('[role=tabpanel] button:contains("some test file")').click
    case insert_into
    when :quiz
      fj("[role=tabpanel] button:contains('#{filename}')").click
      f(".save_quiz_button").click
    when :discussion
      f("#edit_discussion_form_buttons .btn-primary").click
    when :wiki_page
      f(".btn-primary.submit").click
    else
      f(".btn-primary[type=submit]").click
    end
    expect(fln("some test file")).to be_displayed
  end
end
