import codecs
import datetime
import re

from regrippy import BasePlugin, PluginResult, mactime

GUIDS = [
    # Windows XP
    "{75048700-EF1F-11D0-9888-006097DEACF9}",
    "{5E6AB780-7743-11CF-A12B-00AA004AE837}",
    # Windows 7+
    "{CEBFF5CD-ACE2-4F4F-9178-9926F41749EA}",
    "{F4E57C4B-2036-45F0-A9AB-443BCFE33D9F}",
]


class Plugin(BasePlugin):
    """Parses the UserAssist key to get information on program usage"""

    __REGHIVE__ = "NTUSER.DAT"

    def run(self):
        key = self.open_key(
            "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\UserAssist"
        )
        if not key:
            return

        for subkey in key.subkeys():
            if subkey.name() not in GUIDS:
                continue

            count_key = subkey.subkey("Count")
            for entry in count_key.values():
                res = PluginResult(key=count_key, value=entry)
                res.custom["userassist"] = UAObject(entry.name(), entry.value())
                yield res

    def display_human(self, result):
        ua = result.custom["userassist"]
        if ua.last_exec == 0:
            last_exec_str = "(N/A)"
        else:
            last_exec = datetime.date.fromtimestamp(ua.last_exec)
            last_exec_str = last_exec.strftime("%Y-%m-%d %H:%M:%S%z")
        print(f"[{ua.name}]")
        print(f"  Executed {ua.number_of_execs} times")
        print(
            f"  Focused {ua.focus_count} times (total: {datetime.timedelta(seconds=ua.focus_time_secs)})"
        )
        print(f"  Last execution: {last_exec_str}")
        print()

    def display_machine(self, result):
        ua = result.custom["userassist"]
        print(
            mactime(
                name=f"{self.guess_username()} {ua.name};{ua.number_of_execs};{ua.focus_count} {ua.focus_time_secs}",
                mtime=result.mtime,
                atime=ua.last_exec,
            )
        )


class UAObject(object):
    LENGTH_WINXP = 16
    LENGTH_WIN7 = 72

    def __init__(self, name, raw):
        self._raw = raw
        self.name = codecs.encode(name, "rot13")
        for gid, tr in DIR_TRANSLATION.items():
            self.name = re.sub(re.escape(gid), tr, self.name, flags=re.IGNORECASE)

        self.number_of_execs = self._read_nb_execs()
        self.focus_count = self._read_focus_count()
        self.focus_time_secs = self._read_focus_time()
        self.last_exec = self._read_last_exec()

    def _read_nb_execs(self):
        if len(self._raw) == UAObject.LENGTH_WINXP:
            return int.from_bytes(self._raw[4:8], byteorder="little") - 5
        else:
            return int.from_bytes(self._raw[4:8], byteorder="little")

    def _read_focus_count(self):
        if len(self._raw) == UAObject.LENGTH_WINXP:
            return 0

        return int.from_bytes(self._raw[8:12], byteorder="little")

    def _read_focus_time(self):
        if len(self._raw) == UAObject.LENGTH_WINXP:
            return 0

        return int.from_bytes(self._raw[12:16], byteorder="little")

    def _read_last_exec(self):
        timestamp = 0
        if len(self._raw) == UAObject.LENGTH_WINXP:
            timestamp = int.from_bytes(
                self._raw[8:16], byteorder="little", signed=False
            )
        else:
            timestamp = int.from_bytes(
                self._raw[60:68], byteorder="little", signed=False
            )

        no_nano = (
            timestamp // 10000000
        )  # 10000000 - 100 nanosecond intervals in windows timestamp, remove them to get to seconds since windows epoch
        unix = no_nano - 11644473600  # number of seconds between 1/1/1601 and 1/1/1970

        return max(0, unix)  # sometimes "timestamp" is 0, so it gives weird numbers


DIR_TRANSLATION = {
    "{de61d971-5ebc-4f02-a3a9-6c82895e5c04}": "Add or Remove Programs (Control Panel)",
    "{724EF170-A42D-4FEF-9F26-B60E846FBA4F}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Administrative Tools",
    "{a305ce99-f527-492b-8b1a-7e76fa98d6e4}": "Installed Updates",
    "{9E52AB10-F80D-49DF-ACB8-4330F5687855}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows\\\\Burn\\\\Burn",
    "{df7266ac-9274-4867-8d55-3bd661de872d}": "Programs and Features",
    "{D0384E7D-BAC3-4797-8F14-CBA229B392B5}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\Administrative Tools",
    "{C1BAE2D0-10DF-4334-BEDD-7AA20B227A9D}": "%ALLUSERSPROFILE%\\\\OEM Links",
    "{0139D44E-6AFE-49F2-8690-3DAFCAE6FFB8}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs",
    "{A4115719-D62E-491D-AA7C-E74B8BE3B067}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Start Menu",
    "{82A5EA35-D9CD-47C5-9629-E15D2F714E6E}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\StartUp",
    "{B94237E7-57AC-4347-9151-B08C6C32D1F7}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Templates",
    "{0AC0837C-BBF8-452A-850D-79D08E667CA7}": "(My) Computer",
    "{4bfefb45-347d-4006-a5be-ac0cb0567192}": "Conflicts",
    "{6F0CD92B-2E97-45D1-88FF-B0D186B8DEDD}": "Network Connections",
    "{56784854-C6CB-462b-8169-88E350ACB882}": "%USERPROFILE%\\\\Contacts",
    "{82A74AEB-AEB4-465C-A014-D097EE346D63}": "Control Panel",
    "{2B0F765D-C0E9-4171-908E-08A611B84FF6}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Cookies",
    "{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}": "Desktop",
    "{5CE4A5E9-E4EB-479D-B89F-130C02886155}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\DeviceMetadataStore",
    "{7B0DB17D-9CD2-4A93-9733-46CC89022E7C}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Libraries\\\\Documents.library-ms",
    "{374DE290-123F-4565-9164-39C4925E467B}": "%USERPROFILE%\\\\Downloads",
    "{1777F761-68AD-4D8A-87BD-30B759FA33DD}": "%USERPROFILE%\\\\Favorites",
    "{FD228CB7-AE11-4AE3-864C-16F3910AB8FE}": "%windir%\\\\Fonts",
    "{CAC52C1A-B53D-4edc-92D7-6B2E8AC19434}": "Games",
    "{054FAE61-4DD8-4787-80B6-090220C4B700}": "GameExplorer",
    "{D9DC8A3B-B784-432E-A781-5A1130A75963}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows\\\\History",
    "{52528A6B-B9E3-4ADD-B60D-588C2DBA842D}": "Homegroup",
    "{BCB5256F-79F6-4CEE-B725-DC34E402FD46}": "%APPDATA%\\\\Microsoft\\\\Internet Explorer\\\\Quick Launch\\\\User Pinned\\\\ImplicitAppShortcuts",
    "{352481E8-33BE-4251-BA85-6007CAEDCF9D}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows\\\\Temporary Internet Files",
    "{4D9F7874-4E0C-4904-967B-40B0D20C3E4B}": "The Internet",
    "{1B3EA5DC-B587-4786-B4EF-BD1DC332AEAE}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Libraries",
    "{bfb9d5e0-c6a9-404c-b2b2-ae6db6af4968}": "%USERPROFILE%\\\\Links",
    "{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}": "%LOCALAPPDATA% (%USERPROFILE%\\\\AppData\\\\Local)",
    "{A520A1A4-1780-4FF6-BD18-167343C5AF16}": "%USERPROFILE%\\\\AppData\\\\LocalLow",
    "{2A00375E-224C-49DE-B8D1-440DF7EF3DDC}": "%windir%\\\\resources\\\\0409 (code page)",
    "{4BD8D571-6D19-48D3-BE97-422220080E43}": "%USERPROFILE%\\\\Music",
    "{2112AB0A-C86A-4FFE-A368-0DE96E47012E}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Libraries\\\\Music.library-ms",
    "{C5ABBF53-E17F-4121-8900-86626FC2C973}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Network Shortcuts",
    "{D20BEEC4-5CA8-4905-AE3B-BF251EA09B53}": "Network",
    "{2C36C0AA-5812-4b87-BFD0-4CD0DFB19B39}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows Photo Gallery\\\\Original Images",
    "{69D2CF90-FC33-4FB7-9A0C-EBB0F0FCB43C}": "%USERPROFILE%\\\\Pictures\\\\Slide Shows",
    "{A990AE9F-A03B-4E80-94BC-9912D7504104}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Libraries\\\\Pictures.library-ms",
    "{33E28130-4E1E-4676-835A-98395C3BC3BB}": "%USERPROFILE%\\\\Pictures",
    "{DE92C1C7-837F-4F69-A3BB-86E631204A23}": "%USERPROFILE%\\\\Music\\\\Playlists",
    "{76FC4E2D-D6AD-4519-A663-37BD56068185}": "Printers",
    "{9274BD8D-CFD1-41C3-B35E-B13F55A758F4}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Printer Shortcuts",
    "{5E6C858F-0E22-4760-9AFE-EA3317B67173}": "%USERPROFILE% (%SystemDrive%\\\\Users\\\\%USERNAME%)",
    "{62AB5D82-FDC1-4DC3-A9DD-070D1D495D97}": "%ALLUSERSPROFILE% (%ProgramData%, %SystemDrive%\\\\ProgramData)",
    "{905e63b6-c1bf-494e-b29c-65b732d3d21a}": "%ProgramFiles%",
    "{6D809377-6AF0-444b-8957-A3773F02200E}": "%ProgramFiles%",
    "{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}": "%ProgramFiles%",
    "{F7F1ED05-9F6D-47A2-AAAE-29D317C6F066}": "%ProgramFiles%\\\\Common Files",
    "{6365D5A7-0F0D-45E5-87F6-0DA56B6A4F7D}": "%ProgramFiles%\\\\Common Files",
    "{DE974D24-D9C6-4D3E-BF91-F4455120B917}": "%ProgramFiles%\\\\Common Files",
    "{A77F5D77-2E2B-44C3-A6A2-ABA601054A51}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs",
    "{DFDF76A2-C82A-4D63-906A-5644AC457385}": "%PUBLIC% (%SystemDrive%\\\\Users\\\\Public)",
    "{C4AA340D-F20F-4863-AFEF-F87EF2E6BA25}": "%PUBLIC%\\\\Desktop",
    "{ED4824AF-DCE4-45A8-81E2-FC7965083634}": "%PUBLIC%\\\\Documents",
    "{3D644C9B-1FB8-4f30-9B45-F670235F79C0}": "%PUBLIC%\\\\Downloads",
    "{DEBF2536-E1A8-4c59-B6A2-414586476AEA}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\GameExplorer",
    "{48DAF80B-E6CF-4F4E-B800-0E69D84EE384}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Libraries",
    "{3214FAB5-9757-4298-BB61-92A9DEAA44FF}": "%PUBLIC%\\\\Music",
    "{B6EBFB86-6907-413C-9AF7-4FC2ABF07CC5}": "%PUBLIC%\\\\Pictures",
    "{E555AB60-153B-4D17-9F04-A5FE99FC15EC}": "%ALLUSERSPROFILE%\\\\Microsoft\\\\Windows\\\\Ringtones",
    "{2400183A-6185-49FB-A2D8-4A392A602BA3}": "%PUBLIC%\\\\Videos",
    "{52a4f021-7b75-48a9-9f6b-4b87a210bc8f}": "%APPDATA%\\\\Microsoft\\\\Internet Explorer\\\\Quick Launch",
    "{AE50C081-EBD2-438A-8655-8A092E34987A}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Recent",
    "{1A6FDBA2-F42D-4358-A798-B74D745926C5}": "%PUBLIC%\\\\RecordedTV.library-ms",
    "{B7534046-3ECB-4C18-BE4E-64CD4CB7D6AC}": "Recycle Bin",
    "{8AD10C31-2ADB-4296-A8F7-E4701232C972}": "%windir%\\\\Resources",
    "{C870044B-F49E-4126-A9C3-B52A1FF411E8}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows\\\\Ringtones",
    "{3EB685DB-65F9-4CF6-A03A-E3EF65729F3D}": "%APPDATA% (%USERPROFILE%\\\\AppData\\\\Roaming)",
    "{B250C668-F57D-4EE1-A63C-290EE7D1AA1F}": "%PUBLIC%\\\\Music\\\\Sample Music",
    "{C4900540-2379-4C75-844B-64E6FAF8716B}": "%PUBLIC%\\\\Pictures\\\\Sample Pictures",
    "{15CA69B3-30EE-49C1-ACE1-6B5EC372AFB5}": "%PUBLIC%\\\\Music\\\\Sample Playlists",
    "{859EAD94-2E85-48AD-A71A-0969CB56A6CD}": "%PUBLIC%\\\\Videos\\\\Sample Videos",
    "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}": "%USERPROFILE%\\\\Saved Games",
    "{7d1d3a04-debb-4115-95cf-2f29da2920da}": "%USERPROFILE%\\\\Searches",
    "{ee32e446-31ca-4aba-814f-a5ebd2fd6d5e}": "Offline Files",
    "{98ec0e18-2098-4d44-8644-66979315a281}": "Microsoft Office Outlook",
    "{190337d1-b8ca-4121-a639-6d472d16972a}": "Search Results",
    "{8983036C-27C0-404B-8F08-102D10DCFD74}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\SendTo",
    "{7B396E54-9EC5-4300-BE0A-2482EBAE1A26}": "%ProgramFiles%\\\\Windows Sidebar\\\\Gadgets",
    "{A75D362E-50FC-4fb7-AC2C-A8BEAA314493}": "%LOCALAPPDATA%\\\\Microsoft\\\\Windows Sidebar\\\\Gadgets",
    "{625B53C3-AB48-4EC1-BA1F-A1EF4146FC19}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Start Menu",
    "{B97D20BB-F46A-4C97-BA10-5E3608430854}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Start Menu\\\\Programs\\\\StartUp",
    "{43668BF8-C14E-49B2-97C9-747784D784B7}": "Sync Center",
    "{289a9a43-be44-4057-a41b-587a76d7e7f9}": "Sync Results",
    "{0F214138-B1D3-4a90-BBA9-27CBC0C5389A}": "Sync Setup",
    "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}": "%windir%\\\\system32",
    "{D65231B0-B2F1-4857-A4CE-A8E7C6EA7D27}": "%windir%\\\\system32",
    "{A63293E8-664E-48DB-A079-DF759E0509F7}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Templates",
    "{9E3995AB-1F9C-4F13-B827-48B24B6C7174}": "%APPDATA%\\\\Microsoft\\\\Internet Explorer\\\\Quick Launch\\\\User Pinned",
    "{0762D272-C50A-4BB0-A382-697DCD729B80}": "%SystemDrive%\\\\Users",
    "{5CD7AEE2-2219-4A67-B85D-6C9CE15660CB}": "%LOCALAPPDATA%\\\\Programs",
    "{BCBD3057-CA5C-4622-B42D-BC56DB0AE516}": "%LOCALAPPDATA%\\\\Programs\\\\Common",
    "{f3ce0f7c-4901-4acc-8648-d5d44b04ef8f}": "The user's full name",
    "{A302545D-DEFF-464b-ABE8-61C8648D939B}": "Libraries",
    "{18989B1D-99B5-455B-841C-AB7C74E4DDFC}": "%USERPROFILE%\\\\Videos",
    "{491E922F-5643-4AF4-A7EB-4E7A138D8174}": "%APPDATA%\\\\Microsoft\\\\Windows\\\\Libraries\\\\Videos.library-ms",
    "{F38BF404-1D43-42F2-9305-67DE0B28FC23}": "%windir%",
}
