#!/usr/bin/env python3
from controlfloor import *

# returns number of files moved
def move_downloaded_media_to_camera_roll(timeout=60):
    moved_count = 0

    browse_strings       = get_ios_strings("DocumentManager", "BROWSE")
    select_strings       = get_ios_strings("DocumentManager", "SELECT")
    delete_strings       = get_ios_strings("DocumentManager", "DELETE")
    # The "Downloads" cell (a big folder icon) has a label and an identifier.  Don't know if the identifier is
    # localized or not, so I've added the English to be safe.
    downloads_strings    = get_ios_strings("DocumentManager", "DOWNLOADS") + ["Downloads"]
    on_my_device_strings = get_ios_strings("DocumentManager", "ON_MY_DEVICE")
    share_strings        = get_ios_strings("UIKit", "SHARE")
    more_strings         = get_ios_strings("UIKit", "MORE") + ["DOC.itemCollectionMenuButton.Ellipsis"]

    no_downloaded_files_strings = get_ios_strings("DocumentManager", "NO_DOWNLOADED_FILES")

    launchApplication("com.apple.DocumentsApp")
    wait(2)

    elements = getNamedElements("QLOverlayDoneButtonAccessibilityIdentifier")
    # label = "Done"
    # When a file is opened, it stays open even if you kill/restart the file browser.
    # Tapping "Done" will close the file
    if done_button := elements.get("QLOverlayDoneButtonAccessibilityIdentifier", "button", exceptions=False):
        done_button.tap()
        wait(2)

    tap(browse_strings, "button")
    tap(on_my_device_strings, "staticText")
    tap(downloads_strings, "cell")

    wait(1)
    if getElements(no_downloaded_files_strings):
        return 0

    wait_time = 0
    while 1:
        els = getElements(None, "progressIndicator")
        if not els:
            break
        if wait_time > timeout:
            raise Exception("Timed out waiting for file download to complete.  Timeout: %d seconds. [progressIndicator] value is %s" % (timeout, els[0].value))
        progress_message = ", ".join([x.value for x in els])
        print("Waiting for download(s) to complete.  Current progress: " + progress_message)
        wait(10)
        wait_time += 10

    # Each file is nested inside a "cell".  Tapping "..."->"Select" does not
    # scroll the screen, and XCTest will scroll any of these cells onto the
    # screen as necessary, so we don't have to worry about partially offscreen
    # items.
    cells = getElements( None, "cell" )
    while cells:
        for mode in ("save", "delete"):
            # ... Menu in the top-right, label = "More"
            tap(more_strings, "button")
            tap(select_strings,"button")
            wait(1)

            pushDelay(0.1)
            for cell in cells:
                if cell.maxY > 0.8 * deviceInfo.logicalHeight:
                    continue
                cell.tap()
                if mode == "save":
                    moved_count += 1
            popDelay()

            # By deleting exactly what we save to the camera roll, we can scroll through
            # an arbitrary number of files without worrying about scrolling.
            if mode == "delete":
                tap(delete_strings, "button")
                wait(2)
                cells = getElements( None, "cell" )
                continue

            tap(share_strings,"button")
            wait(1)
            menu_cells = getNamedElements(None, ["cell", "button"])
            fix_stack = False
            processId = 0
            bundleId = ""
            if not menu_cells:
                print("Dark Arts...")
                # Begin dark arts...
                # Safari actually invokes the operating-system wide sharing service, which is kind-of-sort-of integrated
                # into the application structure, but also sometimes completely invisible...
                el = getElementAtPoint(150,500) #Just anywhere toward the bottom of the page where the slide-up should be
                if el.processId:
                    processes = send_message("getProcessList")
                    #TODO: decide whether to call this field 'pid' or processId in the API and be done with it
                    for p in processes._:
                        if p.Pid == el.processId and p.Name == "SharingUIService":
                            bundleId = "com.apple.SharingUIService"
                            # You aren't ever supposed to do this yourself
                            fix_stack = True
                            print("Manually setting active app to %s:%d" % (bundleId,el.processId))
                            updateApplication(bundleId=bundleId, processId=el.processId)
                            menu_cells = getNamedElements(None, ["cell", "button"])
                            break
            for e in menu_cells:
                if text_matches_ios_string( e.label, "UIKit", "SAVE_N_ITEMS_ROLLUP" ):
                    e.by_id.tap()
                    wait(1)
                    break
            else:
                if fix_stack:
                    backgroundApplication(bundleId=bundleId, processId=el.processId)
                raise Exception("Could not find \"save\" button")
            if fix_stack:
                backgroundApplication(bundleId=bundleId, processId=el.processId)

    # If everything is deleted, we should see this message:
    getElement(no_downloaded_files_strings)
    return moved_count

cfrun(__name__, move_downloaded_media_to_camera_roll)
