// Copyright 2020 the Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn_native/Surface.h"

#include "common/Platform.h"
#include "dawn_native/ChainUtils_autogen.h"
#include "dawn_native/Instance.h"
#include "dawn_native/SwapChain.h"

#if defined(DAWN_PLATFORM_WINDOWS)
#    include <windows.ui.core.h>
#    include <windows.ui.xaml.controls.h>
#endif  // defined(DAWN_PLATFORM_WINDOWS)

#if defined(DAWN_USE_X11)
#    include "common/xlib_with_undefs.h"
#endif  // defined(DAWN_USE_X11)

namespace dawn::native {

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        Surface::Type value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case Surface::Type::MetalLayer:
                s->Append("MetalLayer");
                break;
            case Surface::Type::WindowsHWND:
                s->Append("WindowsHWND");
                break;
            case Surface::Type::WindowsCoreWindow:
                s->Append("WindowsCoreWindow");
                break;
            case Surface::Type::WindowsSwapChainPanel:
                s->Append("WindowsSwapChainPanel");
                break;
            case Surface::Type::Xlib:
                s->Append("Xlib");
                break;
        }
        return {true};
    }

#if defined(DAWN_ENABLE_BACKEND_METAL)
    bool InheritsFromCAMetalLayer(void* obj);
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)

    MaybeError ValidateSurfaceDescriptor(const InstanceBase* instance,
                                         const SurfaceDescriptor* descriptor) {
        DAWN_INVALID_IF(descriptor->nextInChain == nullptr,
                        "Surface cannot be created with %s. nextInChain is not specified.",
                        descriptor);

        DAWN_TRY(ValidateSingleSType(descriptor->nextInChain,
                                     wgpu::SType::SurfaceDescriptorFromMetalLayer,
                                     wgpu::SType::SurfaceDescriptorFromWindowsHWND,
                                     wgpu::SType::SurfaceDescriptorFromWindowsCoreWindow,
                                     wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel,
                                     wgpu::SType::SurfaceDescriptorFromXlibWindow));

#if defined(DAWN_ENABLE_BACKEND_METAL)
        const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
        FindInChain(descriptor->nextInChain, &metalDesc);
        if (metalDesc) {
            // Check that the layer is a CAMetalLayer (or a derived class).
            DAWN_INVALID_IF(!InheritsFromCAMetalLayer(metalDesc->layer),
                            "Layer must be a CAMetalLayer");
            return {};
        }
#endif  // defined(DAWN_ENABLE_BACKEND_METAL)

#if defined(DAWN_PLATFORM_WINDOWS)
#    if defined(DAWN_PLATFORM_WIN32)
        const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
        FindInChain(descriptor->nextInChain, &hwndDesc);
        if (hwndDesc) {
            DAWN_INVALID_IF(IsWindow(static_cast<HWND>(hwndDesc->hwnd)) == 0, "Invalid HWND");
            return {};
        }
#    endif  // defined(DAWN_PLATFORM_WIN32)
        const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
        FindInChain(descriptor->nextInChain, &coreWindowDesc);
        if (coreWindowDesc) {
            // Validate the coreWindow by query for ICoreWindow interface
            ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
            DAWN_INVALID_IF(coreWindowDesc->coreWindow == nullptr ||
                                FAILED(static_cast<IUnknown*>(coreWindowDesc->coreWindow)
                                           ->QueryInterface(IID_PPV_ARGS(&coreWindow))),
                            "Invalid CoreWindow");
            return {};
        }
        const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
        FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
        if (swapChainPanelDesc) {
            // Validate the swapChainPanel by querying for ISwapChainPanel interface
            ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
            DAWN_INVALID_IF(swapChainPanelDesc->swapChainPanel == nullptr ||
                                FAILED(static_cast<IUnknown*>(swapChainPanelDesc->swapChainPanel)
                                           ->QueryInterface(IID_PPV_ARGS(&swapChainPanel))),
                            "Invalid SwapChainPanel");
            return {};
        }
#endif  // defined(DAWN_PLATFORM_WINDOWS)

#if defined(DAWN_USE_X11)
        const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
        FindInChain(descriptor->nextInChain, &xDesc);
        if (xDesc) {
            // Check the validity of the window by calling a getter function on the window that
            // returns a status code. If the window is bad the call return a status of zero. We
            // need to set a temporary X11 error handler while doing this because the default
            // X11 error handler exits the program on any error.
            XErrorHandler oldErrorHandler =
                XSetErrorHandler([](Display*, XErrorEvent*) { return 0; });
            XWindowAttributes attributes;
            int status = XGetWindowAttributes(reinterpret_cast<Display*>(xDesc->display),
                                              xDesc->window, &attributes);
            XSetErrorHandler(oldErrorHandler);

            DAWN_INVALID_IF(status == 0, "Invalid X Window");
            return {};
        }
#endif  // defined(DAWN_USE_X11)

        return DAWN_FORMAT_VALIDATION_ERROR("Unsupported sType (%s)",
                                            descriptor->nextInChain->sType);
    }

    Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
        : mInstance(instance) {
        ASSERT(descriptor->nextInChain != nullptr);
        const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
        const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
        const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
        const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
        const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
        FindInChain(descriptor->nextInChain, &metalDesc);
        FindInChain(descriptor->nextInChain, &hwndDesc);
        FindInChain(descriptor->nextInChain, &coreWindowDesc);
        FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
        FindInChain(descriptor->nextInChain, &xDesc);
        ASSERT(metalDesc || hwndDesc || xDesc);
        if (metalDesc) {
            mType = Type::MetalLayer;
            mMetalLayer = metalDesc->layer;
        } else if (hwndDesc) {
            mType = Type::WindowsHWND;
            mHInstance = hwndDesc->hinstance;
            mHWND = hwndDesc->hwnd;
        } else if (coreWindowDesc) {
#if defined(DAWN_PLATFORM_WINDOWS)
            mType = Type::WindowsCoreWindow;
            mCoreWindow = static_cast<IUnknown*>(coreWindowDesc->coreWindow);
#endif  // defined(DAWN_PLATFORM_WINDOWS)
        } else if (swapChainPanelDesc) {
#if defined(DAWN_PLATFORM_WINDOWS)
            mType = Type::WindowsSwapChainPanel;
            mSwapChainPanel = static_cast<IUnknown*>(swapChainPanelDesc->swapChainPanel);
#endif  // defined(DAWN_PLATFORM_WINDOWS)
        } else if (xDesc) {
            mType = Type::Xlib;
            mXDisplay = xDesc->display;
            mXWindow = xDesc->window;
        } else {
            UNREACHABLE();
        }
    }

    Surface::~Surface() {
        if (mSwapChain != nullptr) {
            mSwapChain->DetachFromSurface();
            mSwapChain = nullptr;
        }
    }

    NewSwapChainBase* Surface::GetAttachedSwapChain() {
        return mSwapChain.Get();
    }

    void Surface::SetAttachedSwapChain(NewSwapChainBase* swapChain) {
        mSwapChain = swapChain;
    }

    InstanceBase* Surface::GetInstance() {
        return mInstance.Get();
    }

    Surface::Type Surface::GetType() const {
        return mType;
    }

    void* Surface::GetMetalLayer() const {
        ASSERT(mType == Type::MetalLayer);
        return mMetalLayer;
    }

    void* Surface::GetHInstance() const {
        ASSERT(mType == Type::WindowsHWND);
        return mHInstance;
    }
    void* Surface::GetHWND() const {
        ASSERT(mType == Type::WindowsHWND);
        return mHWND;
    }

    IUnknown* Surface::GetCoreWindow() const {
        ASSERT(mType == Type::WindowsCoreWindow);
#if defined(DAWN_PLATFORM_WINDOWS)
        return mCoreWindow.Get();
#else
        return nullptr;
#endif
    }

    IUnknown* Surface::GetSwapChainPanel() const {
        ASSERT(mType == Type::WindowsSwapChainPanel);
#if defined(DAWN_PLATFORM_WINDOWS)
        return mSwapChainPanel.Get();
#else
        return nullptr;
#endif
    }

    void* Surface::GetXDisplay() const {
        ASSERT(mType == Type::Xlib);
        return mXDisplay;
    }
    uint32_t Surface::GetXWindow() const {
        ASSERT(mType == Type::Xlib);
        return mXWindow;
    }

}  // namespace dawn::native
