## Copyright (c) 2021, NVIDIA CORPORATION.  All rights reserved.
##
## NVIDIA CORPORATION and its licensors retain all intellectual property
## and proprietary rights in and to this software, related documentation
## and any modifications thereto.  Any use, reproduction, disclosure or
## distribution of this software and related documentation without an express
## license agreement from NVIDIA CORPORATION is strictly prohibited.
##
from ..acl_delegate import AclDelegate
from ..acl_delegate import ColumnItem
from omni.ui.tests.test_base import OmniUiTest
from pathlib import Path
import asyncio
import omni.kit.app
import omni.ui as ui
import tempfile

CURRENT_PATH = Path(__file__).parent.joinpath("../../../../../data")


class AwaitWithFrame:
    """
    A future-like object that runs the given future and makes sure it's
    always in the given frame's scope. It allows for creating widgets
    asynchronously.
    """

    def __init__(self, frame: ui.Frame, future: asyncio.Future):
        self._frame = frame
        self._future = future

    def __await__(self):
        # create an iterator object from that iterable
        iter_obj = iter(self._future.__await__())

        # infinite loop
        while True:
            try:
                with self._frame:
                    yield next(iter_obj)
            except StopIteration:
                break

        self._frame = None
        self._future = None


class TestAcl(OmniUiTest):
    # Before running each test
    async def setUp(self):
        await super().setUp()
        self._golden_img_dir = CURRENT_PATH.absolute().resolve().joinpath("tests")

    # After running each test
    async def tearDown(self):
        self._golden_img_dir = None
        await super().tearDown()

    async def test_general(self):
        temp = tempfile.NamedTemporaryFile()

        window = await self.create_test_window()
        with window.frame:
            frame = ui.Frame(style={"TreeView.Item": {"color": 0xFFFFFFFF}})

        item = ColumnItem(temp.name)
        delegate = AclDelegate()

        await AwaitWithFrame(frame, delegate.build_widget(item))

        await omni.kit.app.get_app().next_update_async()

        await self.finalize_test(golden_img_dir=self._golden_img_dir)

        temp.close()