/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui;

import android.support.test.uiautomator.UiObjectNotFoundException;

import androidx.test.filters.LargeTest;

import com.android.documentsui.files.FilesActivity;

@LargeTest
public class RenameDocumentUiTest extends ActivityTest<FilesActivity> {

    private final String newName = "kitties.log";

    public RenameDocumentUiTest() {
        super(FilesActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        initTestFiles();
        bots.roots.closeDrawer();
    }

    public void testRenameEnabled_SingleSelection() throws Exception {
        bots.directory.selectDocument(fileName1, 1);
        bots.main.openOverflowMenu();
        bots.main.assertMenuEnabled(R.string.menu_rename, true);

        // Dismiss more options window
        device.pressBack();
    }

    public void testNoRenameSupport_SingleSelection() throws Exception {
        bots.directory.selectDocument(fileNameNoRename, 1);
        bots.main.openOverflowMenu();
        bots.main.assertMenuEnabled(R.string.menu_rename, false);

        // Dismiss more options window
        device.pressBack();
    }

    public void testOneHasRenameSupport_MultipleSelection() throws Exception {
        bots.directory.selectDocument(fileName1, 1);
        bots.directory.selectDocument(fileNameNoRename, 2);
        bots.main.openOverflowMenu();
        bots.main.assertMenuEnabled(R.string.menu_rename, false);

        // Dismiss more options window
        device.pressBack();
    }

    public void testRenameDisabled_MultipleSelection() throws Exception {
        bots.directory.selectDocument(fileName1, 1);
        bots.directory.selectDocument(fileName2, 2);
        bots.main.openOverflowMenu();
        bots.main.assertMenuEnabled(R.string.menu_rename, false);

        // Dismiss more options window
        device.pressBack();
    }

    public void testRenameFile_OkButton() throws Exception {
        bots.directory.selectDocument(fileName1, 1);

        clickRename();

        device.waitForIdle();
        bots.main.setDialogText(newName);

        device.waitForIdle();
        bots.main.clickDialogOkButton();

        bots.directory.waitForDocument(newName);
        bots.directory.assertDocumentsAbsent(fileName1);
        bots.directory.assertDocumentsCount(4);
    }

    public void testRenameFile_Enter() throws Exception {
        bots.directory.selectDocument(fileName1, 1);

        clickRename();

        device.waitForIdle();
        bots.main.setDialogText(newName);

        device.waitForIdle();
        bots.keyboard.pressEnter();

        bots.directory.waitForDocument(newName);
        bots.directory.assertDocumentsAbsent(fileName1);
        bots.directory.assertDocumentsCount(4);
    }

    public void testRenameWithoutChangeIsNoOp() throws Exception {
        bots.directory.selectDocument(fileName1, 1);

        clickRename();

        device.waitForIdle();
        bots.keyboard.pressEnter();

        bots.directory.waitForDocument(fileName1);
        bots.directory.assertDocumentsCount(4);
    }

    public void testRenameFile_Cancel() throws Exception {
        bots.directory.selectDocument(fileName1, 1);

        clickRename();

        bots.main.setDialogText(newName);

        bots.main.clickDialogCancelButton();

        bots.directory.assertDocumentsPresent(fileName1);
        bots.directory.assertDocumentsAbsent(newName);
        bots.directory.assertDocumentsCount(4);

        bots.directory.assertSelection(1);
    }

    public void testRenameDir() throws Exception {
        String oldName = "Dir1";
        String newName = "Dir123";
        bots.directory.selectDocument(oldName, 1);

        clickRename();

        bots.main.setDialogText(newName);

        bots.keyboard.pressEnter();

        bots.directory.assertDocumentsAbsent(oldName);
        bots.directory.assertDocumentsPresent(newName);
        bots.directory.assertDocumentsCount(4);
    }

    public void testRename_NameExists() throws Exception {
        renameWithConflict();

        bots.main.clickDialogCancelButton();

        bots.directory.assertDocumentsPresent(fileName1);
        bots.directory.assertDocumentsPresent(fileName2);
        bots.directory.assertDocumentsCount(4);
    }

    public void testRename_RecoverAfterConflict() throws Exception {
        renameWithConflict();
        device.waitForIdle();

        bots.main.setDialogText(newName);

        device.waitForIdle();
        bots.main.clickDialogOkButton();

        bots.directory.waitForDocument(newName);
        bots.directory.assertDocumentsAbsent(fileName1);
        bots.directory.assertDocumentsCount(4);
    }

    private void renameWithConflict() throws Exception {
        // Check that document with the new name exists
        bots.directory.assertDocumentsPresent(fileName2);
        bots.directory.selectDocument(fileName1, 1);

        clickRename();

        bots.main.assertDialogText(fileName1);
        assertFalse(bots.main.findRenameErrorMessage().exists());
        bots.main.setDialogText(fileName2);
        bots.keyboard.pressEnter();
        assertTrue(bots.main.findRenameErrorMessage().exists());
    }

    private void clickRename() throws UiObjectNotFoundException {
        if (!bots.main.waitForActionModeBarToAppear()) {
            throw new UiObjectNotFoundException("ActionMode bar not found");
        }
        bots.main.clickActionbarOverflowItem("Rename");
        device.waitForIdle();
    }
}