#!/usr/bin/env python3
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
#
# SPDX-License-Identifier: GPL-3.0-or-later
# SPDX-FileCopyrightText: Michael Terry

import os
import shutil
from datetime import datetime

from dogtail.predicate import GenericPredicate
from dogtail.rawinput import keyCombo
from gi.repository import GLib

from . import BaseTest, ResticMixin


class RestoreTest(BaseTest):
    __test__ = False

    def setUp(self):
        super().setUp()
        self.folder = self.get_config(
            "default", "folder", fallback="deja-dup-test", required=False
        )
        self.filename = self.srcdir + "/[t](e?s*)' t.\"txt"
        self.contents = datetime.now().isoformat()
        open(self.filename, "w").write(self.contents)

    def walk_backup(self, app):
        window = self.get_dialog(app)
        window.button("Back Up").click()

        self.wait_for(
            lambda: app.findChild(
                GenericPredicate(roleName="text", label="Encryption password"),
                retry=False,
                requireResult=False,
            ),
            timeout=300,
        )
        window = self.get_alert(app)
        window.child(roleName="text", label="Encryption password").text = "test-restore"

        # Confirm password if we are doing an initial backup
        confirm = window.findChild(
            GenericPredicate(roleName="text", label="Confirm password"),
            retry=False,
            requireResult=False,
        )
        if confirm:
            confirm.text = "test-restore"

        window.button("Continue").click()

        self.wait_for_banner(app, "Pause")

    def walk_restore(self, app):
        shutil.rmtree(self.srcdir)

        window = self.get_dialog(app)
        window.button("Search").click()

        # Switched to restore pane. Enter password if using restic, which
        # unlike duplicity, does not keep unencrypted metadata locally cached.
        if self.restic:
            self.enter_browser_password(app, "test-restore")

        # Select most recent date
        app.child(roleName="list item").click()

        if self.restic:
            self.wait_for_file_manager()
            return

        # Now select all.
        search = app.child(roleName="toggle button", name="Search")
        self.wait_for(lambda: search.sensitive, timeout=300)
        keyCombo("<Control>a")

        # And start restore
        self.click_restore_button(app)
        window = self.get_dialog(app)
        window.button("Restore").click()  # to where

        self.enter_browser_password(app, "test-restore")

        self.wait_for_banner(app, "Stop", check_first=False)

        test_file = open(self.filename, "r")
        assert test_file.read(None) == self.contents

    def test_simple_cycle(self):
        app = self.cmd()

        app.childNamed("Create Your First Backup…").click()
        self.walk_backup(app)

        self.set_string("last-run", "")  # go back to welcome screen

        app.childNamed("Restore From a Previous Backup…").click()
        self.walk_restore(app)


class LocalRestoreTest(RestoreTest):
    __test__ = True

    def setUp(self):
        super().setUp()
        self.set_string("backend", "local")
        self.set_string("folder", self.rootdir + "/dest", child="local")


class ResticLocalRestoreTest(ResticMixin, LocalRestoreTest):
    def setUp(self):
        super().setUp()
        self.set_string("folder", self.rootdir + "/dest-restic", child="local")


class GoogleRestoreTest(RestoreTest):
    __test__ = True

    def setUp(self):
        super().setUp()
        if not int(self.get_config("google", "enabled", fallback="0")):
            self.skipTest("Google not enabled")
        self.set_string("backend", "google")
        self.set_string("folder", self.folder, child="google")


class ResticGoogleRestoreTest(ResticMixin, GoogleRestoreTest):
    def setUp(self):
        super().setUp()
        self.set_string("folder", self.folder + "-restic", child="google")


class MicrosoftRestoreTest(RestoreTest):
    __test__ = True

    def setUp(self):
        super().setUp()
        if not int(self.get_config("microsoft", "enabled", fallback="0")):
            self.skipTest("Microsoft not enabled")
        self.set_string("backend", "microsoft")
        self.set_string("folder", self.folder, child="microsoft")


class ResticMicrosoftRestoreTest(ResticMixin, MicrosoftRestoreTest):
    def setUp(self):
        super().setUp()
        self.set_string("folder", self.folder + "-restic", child="microsoft")


class RemoteRestoreTest(RestoreTest):
    __test__ = True

    def setUp(self):
        super().setUp()
        uri = self.get_config("remote", "uri")
        self.set_string("backend", "remote")
        self.set_string("uri", uri, child="remote")
        self.set_string("folder", self.folder, child="remote")


class ResticRemoteRestoreTest(ResticMixin, RemoteRestoreTest):
    def setUp(self):
        super().setUp()
        self.set_string("folder", self.folder + "-restic", child="remote")


class RcloneRestoreTest(RestoreTest):
    __test__ = True

    def setUp(self):
        super().setUp()
        self.set_string("backend", "rclone")
        self.set_string("remote", ":local", child="rclone")
        self.set_string("folder", self.rootdir + "/dest", child="rclone")


class ResticRcloneRestoreTest(ResticMixin, RcloneRestoreTest):
    def setUp(self):
        super().setUp()
        self.set_string("folder", self.rootdir + "/dest-restic", child="rclone")
