//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_libc_calls
#endif

#include "common/apple_platform_utils.h"

#include "common/debug.h"
#include "common/system_utils.h"

#include <Foundation/Foundation.h>
#include <Metal/Metal.h>

namespace angle
{

bool IsMetalRendererAvailable()
{
#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
    static bool queriedMachineModel    = false;
    static bool machineModelSufficient = true;

    if (!queriedMachineModel)
    {
        queriedMachineModel = true;

        std::string fullMachineModel;
        if (GetMacosMachineModel(&fullMachineModel))
        {
            using MachineModelVersion = std::pair<int32_t, int32_t>;

            std::string name;
            MachineModelVersion version;
            ParseMacMachineModel(fullMachineModel, &name, &version.first, &version.second);

            std::optional<MachineModelVersion> minVersion;
            if (name == "MacBookAir")
            {
                minVersion = {8, 1};  // MacBook Air (Retina, 13-inch, 2018)
            }
            else if (name == "MacBookPro")
            {
                minVersion = {13, 1};  // MacBook Pro (13-inch, 2016)
            }
            else if (name == "MacBook")
            {
                minVersion = {9, 1};  // MacBook (Retina, 12-inch, Early 2016)
            }
            else if (name == "Macmini")
            {
                minVersion = {8, 1};  // Mac mini (2018)
            }
            else if (name == "iMac")
            {
                minVersion = {17, 1};  // iMac (Retina 5K, 27-inch, Late 2015)
            }
            else if (name == "iMacPro")
            {
                minVersion = {1, 1};  // iMac Pro
            }

            if (minVersion.has_value() && version < minVersion.value())
            {
                WARN() << "Disabling Metal because machine model \"" << fullMachineModel
                       << "\" is below the minium supported version.";
                machineModelSufficient = false;
            }
        }
    }

    if (!machineModelSufficient)
    {
        ASSERT(queriedMachineModel);
        return false;
    }
#endif

#if defined(ANGLE_PLATFORM_MACOS) && defined(__aarch64__)
    NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    if (systemVersion.majorVersion == 15 && systemVersion.minorVersion == 0)
    {
        // On ARM64 MacOS 15.0.x, Metal Shader with newLibraryWithSource didn't work,
        // if the executable path contains non-ASCII characters.
        // Bug: https://issues.chromium.org/issues/389559087
        std::string executableName = GetExecutablePath();
        for (char c : executableName)
        {
            if (static_cast<unsigned char>(c) > 127)
            {
                return false;
            }
        }
    }
#endif

    static bool gpuFamilySufficient = []() -> bool {
        ANGLE_APPLE_OBJC_SCOPE
        {
            auto device = [MTLCreateSystemDefaultDevice() ANGLE_APPLE_AUTORELEASE];
            if (!device)
            {
                return false;
            }
#if TARGET_OS_MACCATALYST && __IPHONE_OS_VERSION_MIN_REQUIRED < 160000
            // Devices in family 1, such as MacBookPro11,4, cannot use ANGLE's Metal backend.
            return [device supportsFamily:MTLGPUFamilyMacCatalyst2];
#elif TARGET_OS_MACCATALYST || TARGET_OS_OSX
            // Devices in family 1, such as MacBookPro11,4, cannot use ANGLE's Metal backend.
            return [device supportsFamily:MTLGPUFamilyMac2];
#else
            // Devices starting with A9 onwards are supported. Simulator is supported as per
            // definition that running simulator on Mac Family 1 devices is not supported.
            return true;
#endif
        }
    }();
    return gpuFamilySufficient;
}

#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
bool GetMacosMachineModel(std::string *outMachineModel)
{
    io_service_t platformExpert = IOServiceGetMatchingService(
        kIOMainPortDefault, IOServiceMatching("IOPlatformExpertDevice"));

    if (platformExpert == IO_OBJECT_NULL)
    {
        return false;
    }

    CFDataRef modelData = static_cast<CFDataRef>(
        IORegistryEntryCreateCFProperty(platformExpert, CFSTR("model"), kCFAllocatorDefault, 0));
    if (modelData == nullptr)
    {
        IOObjectRelease(platformExpert);
        return false;
    }

    *outMachineModel = reinterpret_cast<const char *>(CFDataGetBytePtr(modelData));

    IOObjectRelease(platformExpert);
    CFRelease(modelData);

    return true;
}

bool ParseMacMachineModel(const std::string &identifier,
                          std::string *type,
                          int32_t *major,
                          int32_t *minor)
{
    size_t numberLoc = identifier.find_first_of("0123456789");
    if (numberLoc == std::string::npos)
    {
        return false;
    }

    size_t commaLoc = identifier.find(',', numberLoc);
    if (commaLoc == std::string::npos || commaLoc >= identifier.size())
    {
        return false;
    }

    const char *numberPtr = &identifier[numberLoc];
    const char *commaPtr  = &identifier[commaLoc + 1];
    char *endPtr          = nullptr;

    int32_t majorTmp = static_cast<int32_t>(std::strtol(numberPtr, &endPtr, 10));
    if (endPtr == numberPtr)
    {
        return false;
    }

    int32_t minorTmp = static_cast<int32_t>(std::strtol(commaPtr, &endPtr, 10));
    if (endPtr == commaPtr)
    {
        return false;
    }

    *major = majorTmp;
    *minor = minorTmp;
    *type  = identifier.substr(0, numberLoc);

    return true;
}
#endif

}  // namespace angle
