// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package filemanager

import (
	"context"
	"os"
	"path/filepath"
	"time"

	"chromiumos/tast/errors"
	"chromiumos/tast/fsutil"
	"chromiumos/tast/local/chrome"
	"chromiumos/tast/local/chrome/ui"
	"chromiumos/tast/local/chrome/ui/filesapp"
	"chromiumos/tast/local/chrome/uiauto/faillog"
	"chromiumos/tast/local/input"
	"chromiumos/tast/testing"
)

// TestFunc contains the contents of the test itself.
type testFunc func(ctx context.Context, s *testing.State, files *filesapp.FilesApp, zipFiles []string)

// TestEntry contains the function used in the test along with the names of the ZIP files the test is using.
type testEntry struct {
	TestCase testFunc
	ZipFiles []string
}

func init() {
	testing.AddTest(&testing.Test{
		Func: ZipMount,
		Desc: "Tests Files app mounting workflow",
		Contacts: []string{
			"jboulic@chromium.org",
			"fdegros@chromium.org",
			"chromeos-files-syd@google.com",
		},
		Attr:         []string{"group:mainline", "informational"},
		SoftwareDeps: []string{"chrome"},
		Data: []string{
			"Encrypted_AES-256.zip",
			"Encrypted_ZipCrypto.zip",
			"Texts.7z",
			"Texts.rar",
			"Texts.zip",
		},
		Params: []testing.Param{{
			Name: "mount_single_7z",
			Val: testEntry{
				TestCase: testMountingSingleZipFile,
				ZipFiles: []string{"Texts.7z"},
			},
		}, {
			Name: "mount_single_rar",
			Val: testEntry{
				TestCase: testMountingSingleZipFile,
				ZipFiles: []string{"Texts.rar"},
			},
		}, {
			Name: "mount_single_zip",
			Val: testEntry{
				TestCase: testMountingSingleZipFile,
				ZipFiles: []string{"Texts.zip"},
			},
		}, {
			Name: "cancel_multiple",
			Val: testEntry{
				TestCase: testCancelingMultiplePasswordDialogs,
				ZipFiles: []string{"Encrypted_AES-256.zip", "Encrypted_ZipCrypto.zip"},
			},
		}, {
			Name: "mount_multiple",
			Val: testEntry{
				TestCase: testMountingMultipleZipFiles,
				ZipFiles: []string{"Encrypted_AES-256.zip", "Encrypted_ZipCrypto.zip", "Texts.zip"},
			},
		}},
	})
}

func ZipMount(ctx context.Context, s *testing.State) {
	testParams := s.Param().(testEntry)
	zipFiles := testParams.ZipFiles

	// TODO(nigeltao): remove "FilesArchivemount" after it gets flipped to
	// enabled-by-default (scheduled for M94) and before the feature flag
	// expires (scheduled for M100). crbug.com/1216245
	cr, err := chrome.New(ctx, chrome.EnableFeatures("FilesArchivemount", "FilesZipMount"))
	if err != nil {
		s.Fatal("Cannot start Chrome: ", err)
	}
	defer cr.Close(ctx)

	// Load ZIP files.
	for _, zipFile := range zipFiles {
		zipFileLocation := filepath.Join(filesapp.DownloadPath, zipFile)

		if err := fsutil.CopyFile(s.DataPath(zipFile), zipFileLocation); err != nil {
			s.Fatalf("Cannot copy ZIP file to %s: %s", zipFileLocation, err)
		}
		defer os.Remove(zipFileLocation)
	}

	// Open the test API.
	tconn, err := cr.TestAPIConn(ctx)
	if err != nil {
		s.Fatal("Cannot create test API connection: ", err)
	}
	defer faillog.DumpUITreeOnError(ctx, s.OutDir(), s.HasError, tconn)

	// Open the Files App.
	files, err := filesapp.Launch(ctx, tconn)
	if err != nil {
		s.Fatal("Cannot launch the Files App: ", err)
	}
	defer files.Release(ctx)

	// Open the Downloads folder.
	if err := files.OpenDownloads(ctx); err != nil {
		s.Fatal("Cannot open Downloads folder: ", err)
	}

	// Find and click the 'Name' button to order the file entries alphabetically.
	// Polling is used since the 'Name' button is not always clickable at the time the corresponding node is found.
	if err := testing.Poll(ctx, func(ctx context.Context) error {
		params := ui.FindParams{
			Name: "Name",
			Role: ui.RoleTypeButton,
		}

		orderByNameButton, err := files.Root.Descendant(ctx, params)
		if err != nil {
			return errors.New("name button still not found")
		}
		defer orderByNameButton.Release(ctx)

		if err := orderByNameButton.LeftClick(ctx); err != nil {
			return errors.New("still unable to click name button to sort files alphabetically")
		}

		return nil
	}, &testing.PollOptions{Timeout: 15 * time.Second}); err != nil {
		s.Fatal("Cannot click 'Name' button: ", err)
	}

	// Wait until the ZIP files are correctly ordered in the list box.
	if err := testing.Poll(ctx, func(ctx context.Context) error {
		params := ui.FindParams{
			Role:  ui.RoleTypeListBox,
			State: map[ui.StateType]bool{ui.StateTypeFocusable: true, ui.StateTypeMultiselectable: true, ui.StateTypeVertical: true},
		}

		listBox, err := files.Root.Descendant(ctx, params)
		if err != nil {
			return testing.PollBreak(err)
		}
		defer listBox.Release(ctx)

		nodes, err := listBox.Descendants(ctx, ui.FindParams{Role: ui.RoleTypeListBoxOption})
		if err != nil {
			return testing.PollBreak(err)
		}
		defer nodes.Release(ctx)

		// The names of the descendant nodes should be ordered alphabetically.
		for i, node := range nodes {
			if node.Name != zipFiles[i] {
				return errors.New("the files are still not ordered properly")
			}
		}

		return nil
	}, &testing.PollOptions{Timeout: 15 * time.Second}); err != nil {
		s.Fatal("Cannot sort ZIP files properly in the Files app list box: ", err)
	}

	testParams.TestCase(ctx, s, files, zipFiles)
}

// waitUntilPasswordDialogExists waits for the password dialog to display for a specific encrypted ZIP file.
func waitUntilPasswordDialogExists(ctx context.Context, files *filesapp.FilesApp, fileName string) error {
	return testing.Poll(ctx, func(ctx context.Context) error {
		// Get reference to the current password dialog.
		params := ui.FindParams{
			Role: ui.RoleTypeDialog,
		}

		passwordDialog, err := files.Root.Descendant(ctx, params)
		if err != nil {
			return errors.New("password dialog still not found")
		}
		defer passwordDialog.Release(ctx)

		// Look for expected file name label within the current dialog.
		params = ui.FindParams{
			Name: fileName,
			Role: ui.RoleTypeStaticText,
		}
		exists, err := passwordDialog.DescendantExists(ctx, params)
		if err != nil {
			return errors.Wrap(err, "failed to look for file name label")
		}
		if !exists {
			return errors.New("expected file name label still not found")
		}

		return nil
	}, &testing.PollOptions{Timeout: 15 * time.Second})
}

// checkAndUnmountZipFile checks that a given ZIP file is correctly mounted and click the 'eject' button to unmount it.
func checkAndUnmountZipFile(ctx context.Context, s *testing.State, files *filesapp.FilesApp, zipFile string) {
	// Find and open the mounted ZIP file.
	params := ui.FindParams{
		Name: zipFile,
		Role: ui.RoleTypeTreeItem,
	}

	treeItem, err := files.Root.DescendantWithTimeout(ctx, params, 5*time.Second)
	if err != nil {
		s.Fatalf("Cannot find tree item for %s: %v", zipFile, err)
	}
	defer treeItem.Release(ctx)

	if err := treeItem.LeftClick(ctx); err != nil {
		s.Fatal("Cannot open mounted ZIP file: ", err)
	}

	// Ensure that the Files App is displaying the content of the mounted ZIP file.
	params = ui.FindParams{
		Name: "Files - " + zipFile,
		Role: ui.RoleTypeRootWebArea,
	}

	if err := files.Root.WaitUntilDescendantExists(ctx, params, 5*time.Second); err != nil {
		s.Fatal("Cannot see content of mounted ZIP file: ", err)
	}

	// The test ZIP files are all expected to contain a single "Texts" folder.
	var zipContentDirectoryLabel = "Texts"

	// Check content of mounted ZIP file.
	params = ui.FindParams{
		Name: zipContentDirectoryLabel,
		Role: ui.RoleTypeListBoxOption,
	}

	if err := files.Root.WaitUntilDescendantExists(ctx, params, 5*time.Second); err != nil {
		s.Fatalf("Cannot see directory %s in mounted ZIP file: %v", zipContentDirectoryLabel, err)
	}

	// Find the eject button within the appropriate tree item.
	params = ui.FindParams{
		Name: "Eject device",
		Role: ui.RoleTypeButton,
	}

	ejectButton, err := treeItem.DescendantWithTimeout(ctx, params, 5*time.Second)
	if err != nil {
		s.Fatal("Cannot find eject button: ", err)
	}
	defer ejectButton.Release(ctx)

	// Click eject button to unmount the ZIP file.
	if err := ejectButton.LeftClick(ctx); err != nil {
		s.Fatal("Cannot click eject button: ", err)
	}

	// Check that the tree item corresponding to the previously mounted ZIP file was removed.
	params = ui.FindParams{
		Name: zipFile,
		Role: ui.RoleTypeTreeItem,
	}

	if err = files.Root.WaitUntilDescendantGone(ctx, params, 5*time.Second); err != nil {
		s.Fatalf("%s is still mounted: %v", zipFile, err)
	}
}

func testMountingSingleZipFile(ctx context.Context, s *testing.State, files *filesapp.FilesApp, zipFiles []string) {
	if len(zipFiles) != 1 {
		s.Fatal("Unexpected length for zipFiles")
	}
	zipFile := zipFiles[0]

	// Select ZIP file.
	if err := files.WaitForFile(ctx, zipFile, 5*time.Second); err != nil {
		s.Fatal("Cannot wait for test ZIP file: ", err)
	}

	if err := files.SelectFile(ctx, zipFile); err != nil {
		s.Fatal("Cannot select ZIP file: ", err)
	}

	// Wait for Open button in the top bar.
	params := ui.FindParams{
		Name: "Open",
		Role: ui.RoleTypeButton,
	}

	open, err := files.Root.DescendantWithTimeout(ctx, params, 5*time.Second)
	if err != nil {
		s.Fatal("Cannot find Open menu item: ", err)
	}
	defer open.Release(ctx)

	// Mount ZIP file.
	if err := open.LeftClick(ctx); err != nil {
		s.Fatal("Cannot mount ZIP file: ", err)
	}

	checkAndUnmountZipFile(ctx, s, files, zipFile)
}

func testCancelingMultiplePasswordDialogs(ctx context.Context, s *testing.State, files *filesapp.FilesApp, zipFiles []string) {
	// Define keyboard to perform keyboard shortcuts.
	ew, err := input.Keyboard(ctx)
	if err != nil {
		s.Fatal("Cannot create keyboard: ", err)
	}
	defer ew.Close()

	// Select the 2 encrypted ZIP files.
	if err := files.SelectMultipleFiles(ctx, zipFiles); err != nil {
		s.Fatal("Cannot perform multi-selection on the encrypted files: ", err)
	}

	// Press Enter.
	if err := ew.Accel(ctx, "Enter"); err != nil {
		s.Fatal("Cannot press 'Enter': ", err)
	}

	// Wait until the password dialog is active for the first encrypted ZIP archive.
	if err := waitUntilPasswordDialogExists(ctx, files, zipFiles[0]); err != nil {
		s.Fatalf("Cannot find password dialog for %s : %v", zipFiles[0], err)
	}

	// Press Esc.
	if err := ew.Accel(ctx, "Esc"); err != nil {
		s.Fatal("Cannot press 'Esc': ", err)
	}

	// Wait until the password dialog is active for the second encrypted ZIP archive.
	if err := waitUntilPasswordDialogExists(ctx, files, zipFiles[1]); err != nil {
		s.Fatalf("Cannot find password dialog for %s : %v", zipFiles[1], err)
	}

	// Click the 'Cancel' button.
	params := ui.FindParams{
		Name: "Cancel",
		Role: ui.RoleTypeButton,
	}

	cancel, err := files.Root.DescendantWithTimeout(ctx, params, 5*time.Second)
	if err != nil {
		s.Fatal("Cannot find password dialog cancel button: ", err)
	}
	defer cancel.Release(ctx)

	if err := cancel.LeftClick(ctx); err != nil {
		s.Fatal("Cannot cancel password dialog: ", err)
	}

	// Checks that the password dialog is not displayed anymore.
	params = ui.FindParams{
		Name: "Password",
		Role: ui.RoleTypeDialog,
	}

	if err = files.Root.WaitUntilDescendantGone(ctx, params, 5*time.Second); err != nil {
		s.Fatal("The password dialog is still displayed: ", err)
	}
}

func testMountingMultipleZipFiles(ctx context.Context, s *testing.State, files *filesapp.FilesApp, zipFiles []string) {
	// Define keyboard to perform keyboard shortcuts.
	ew, err := input.Keyboard(ctx)
	if err != nil {
		s.Fatal("Cannot create keyboard: ", err)
	}
	defer ew.Close()

	// Select the 3 encrypted ZIP files.
	if err := files.SelectMultipleFiles(ctx, zipFiles); err != nil {
		s.Fatal("Cannot perform multi-selection on the encrypted files: ", err)
	}

	// Press Enter.
	if err := ew.Accel(ctx, "Enter"); err != nil {
		s.Fatal("Cannot press 'Enter': ", err)
	}

	// Wait until the password dialog is active for the first encrypted ZIP archive.
	if err := waitUntilPasswordDialogExists(ctx, files, zipFiles[0]); err != nil {
		s.Fatalf("Cannot find password dialog for %s : %v", zipFiles[0], err)
	}

	// Enter wrong password.
	params := ui.FindParams{
		Role:  ui.RoleTypeTextField,
		State: map[ui.StateType]bool{ui.StateTypeEditable: true, ui.StateTypeFocusable: true, ui.StateTypeProtected: true, ui.StateTypeFocused: true},
	}

	if err := files.Root.WaitUntilDescendantExists(ctx, params, 15*time.Second); err != nil {
		s.Fatal("Cannot find password input field: ", err)
	}

	if err := ew.Type(ctx, "wrongPassword"); err != nil {
		s.Fatal("Cannot enter 'wrongPassword': ", err)
	}

	// Validate password.
	if err := ew.Accel(ctx, "Enter"); err != nil {
		s.Fatal("Cannot validate password by pressing 'Enter': ", err)
	}

	// Check that the password dialog is still active for the first encrypted ZIP archive.
	if err := waitUntilPasswordDialogExists(ctx, files, zipFiles[0]); err != nil {
		s.Fatalf("Cannot find password dialog for %s : %v", zipFiles[0], err)
	}

	// Check that "Invalid password" displays on the UI.
	params = ui.FindParams{
		Name: "Invalid password",
		Role: ui.RoleTypeStaticText,
	}

	if err := files.Root.WaitUntilDescendantExists(ctx, params, 15*time.Second); err != nil {
		s.Fatal("Cannot find 'Invalid password': ", err)
	}

	// Enter right password.
	if err := ew.Type(ctx, "password"); err != nil {
		s.Fatal("Cannot enter 'password': ", err)
	}

	// Validate password.
	if err := ew.Accel(ctx, "Enter"); err != nil {
		s.Fatal("Cannot validate the name of the new directory: ", err)
	}

	// Check that the password dialog is active for the second encrypted ZIP archive.
	if err := waitUntilPasswordDialogExists(ctx, files, zipFiles[1]); err != nil {
		s.Fatalf("Cannot find password dialog for %s : %v", zipFiles[1], err)
	}

	// Enter right password.
	if err := ew.Type(ctx, "password"); err != nil {
		s.Fatal("Cannot enter 'password': ", err)
	}

	// Click Unlock.
	params = ui.FindParams{
		Name: "Unlock",
		Role: ui.RoleTypeButton,
	}

	unlock, err := files.Root.DescendantWithTimeout(ctx, params, 5*time.Second)
	if err != nil {
		s.Fatal("Cannot find password dialog cancel button: ", err)
	}
	defer unlock.Release(ctx)

	if err := unlock.LeftClick(ctx); err != nil {
		s.Fatal("Cannot validate password with the Unlock button: ", err)
	}

	// Checks that the password dialog is not displayed anymore.
	params = ui.FindParams{
		Name: "Password",
		Role: ui.RoleTypeDialog,
	}

	if err = files.Root.WaitUntilDescendantGone(ctx, params, 5*time.Second); err != nil {
		s.Fatal("The password dialog is still displayed: ", err)
	}

	// Check that the 3 zip files have been mounted correctly and unmount them.
	for _, zipFile := range zipFiles {
		checkAndUnmountZipFile(ctx, s, files, zipFile)
	}
}
