// 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 "dawn/common/Platform.h"
#include "dawn/native/ChainUtils_autogen.h"
#include "dawn/native/Instance.h"
#include "dawn/native/SwapChain.h"

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

#if defined(DAWN_USE_X11)
#include "dawn/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::AndroidWindow:
            s->Append("AndroidWindow");
            break;
        case Surface::Type::MetalLayer:
            s->Append("MetalLayer");
            break;
        case Surface::Type::WaylandSurface:
            s->Append("WaylandSurface");
            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::XlibWindow:
            s->Append("XlibWindow");
            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::SurfaceDescriptorFromAndroidNativeWindow,
        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 DAWN_PLATFORM_IS(ANDROID)
    const SurfaceDescriptorFromAndroidNativeWindow* androidDesc = nullptr;
    FindInChain(descriptor->nextInChain, &androidDesc);
    // Currently the best validation we can do since it's not possible to check if the pointer
    // to a ANativeWindow is valid.
    if (androidDesc) {
        DAWN_INVALID_IF(androidDesc->window == nullptr, "Android window is not set.");
        return {};
    }
#endif  // DAWN_PLATFORM_IS(ANDROID)

#if DAWN_PLATFORM_IS(WINDOWS)
#if DAWN_PLATFORM_IS(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  // DAWN_PLATFORM_IS(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  // DAWN_PLATFORM_IS(WINDOWS)

#if defined(DAWN_USE_WAYLAND)
    const SurfaceDescriptorFromWaylandSurface* waylandDesc = nullptr;
    FindInChain(descriptor->nextInChain, &waylandDesc);
    if (waylandDesc) {
        // Unfortunately we can't check the validity of wayland objects. Only that they
        // aren't nullptr.
        DAWN_INVALID_IF(waylandDesc->display == nullptr, "Wayland display is nullptr.");
        DAWN_INVALID_IF(waylandDesc->surface == nullptr, "Wayland surface is nullptr.");
        return {};
    }
#endif  // defined(DAWN_USE_X11)

#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);
}

// static
Surface* Surface::MakeError(InstanceBase* instance) {
    return new Surface(instance, ErrorMonad::kError);
}

Surface::Surface(InstanceBase* instance, ErrorTag tag) : ErrorMonad(tag), mInstance(instance) {}

Surface::Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor)
    : ErrorMonad(), mInstance(instance) {
    ASSERT(descriptor->nextInChain != nullptr);
    const SurfaceDescriptorFromAndroidNativeWindow* androidDesc = nullptr;
    const SurfaceDescriptorFromMetalLayer* metalDesc = nullptr;
    const SurfaceDescriptorFromWindowsHWND* hwndDesc = nullptr;
    const SurfaceDescriptorFromWindowsCoreWindow* coreWindowDesc = nullptr;
    const SurfaceDescriptorFromWindowsSwapChainPanel* swapChainPanelDesc = nullptr;
    const SurfaceDescriptorFromWaylandSurface* waylandDesc = nullptr;
    const SurfaceDescriptorFromXlibWindow* xDesc = nullptr;
    FindInChain(descriptor->nextInChain, &androidDesc);
    FindInChain(descriptor->nextInChain, &metalDesc);
    FindInChain(descriptor->nextInChain, &hwndDesc);
    FindInChain(descriptor->nextInChain, &coreWindowDesc);
    FindInChain(descriptor->nextInChain, &swapChainPanelDesc);
    FindInChain(descriptor->nextInChain, &xDesc);
    if (metalDesc) {
        mType = Type::MetalLayer;
        mMetalLayer = metalDesc->layer;
    } else if (androidDesc) {
        mType = Type::AndroidWindow;
        mAndroidNativeWindow = androidDesc->window;
    } else if (waylandDesc) {
        mType = Type::WaylandSurface;
        mWaylandDisplay = waylandDesc->display;
        mWaylandSurface = waylandDesc->surface;
    } else if (hwndDesc) {
        mType = Type::WindowsHWND;
        mHInstance = hwndDesc->hinstance;
        mHWND = hwndDesc->hwnd;
    } else if (coreWindowDesc) {
#if DAWN_PLATFORM_IS(WINDOWS)
        mType = Type::WindowsCoreWindow;
        mCoreWindow = static_cast<IUnknown*>(coreWindowDesc->coreWindow);
#endif  // DAWN_PLATFORM_IS(WINDOWS)
    } else if (swapChainPanelDesc) {
#if DAWN_PLATFORM_IS(WINDOWS)
        mType = Type::WindowsSwapChainPanel;
        mSwapChainPanel = static_cast<IUnknown*>(swapChainPanelDesc->swapChainPanel);
#endif  // DAWN_PLATFORM_IS(WINDOWS)
    } else if (xDesc) {
        mType = Type::XlibWindow;
        mXDisplay = xDesc->display;
        mXWindow = xDesc->window;
    } else {
        UNREACHABLE();
    }
}

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

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

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

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

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

void* Surface::GetAndroidNativeWindow() const {
    ASSERT(!IsError());
    ASSERT(mType == Type::AndroidWindow);
    return mAndroidNativeWindow;
}

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

void* Surface::GetWaylandDisplay() const {
    ASSERT(mType == Type::WaylandSurface);
    return mWaylandDisplay;
}

void* Surface::GetWaylandSurface() const {
    ASSERT(mType == Type::WaylandSurface);
    return mWaylandSurface;
}

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

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

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

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

}  // namespace dawn::native
