/*
 * Copyright (c) 2018-2022 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "arm_compute/core/GPUTarget.h"

#include "arm_compute/core/Log.h"

#include <map>
#include <regex>

namespace
{
arm_compute::GPUTarget get_valhall_target(const std::string &version)
{
    if (version.find("G77") != std::string::npos)
    {
        return arm_compute::GPUTarget::G77;
    }
    else if (version.find("G57") != std::string::npos)
    {
        return arm_compute::GPUTarget::G57;
    }
    if (version.find("G68") != std::string::npos)
    {
        return arm_compute::GPUTarget::G68;
    }
    if (version.find("G78AE") != std::string::npos)
    {
        return arm_compute::GPUTarget::G78AE;
    }
    if (version.find("G78") != std::string::npos)
    {
        return arm_compute::GPUTarget::G78;
    }
    else if (version.find("G710") != std::string::npos)
    {
        return arm_compute::GPUTarget::G710;
    }
    else if (version.find("G610") != std::string::npos)
    {
        return arm_compute::GPUTarget::G610;
    }
    else if (version.find("G510") != std::string::npos)
    {
        return arm_compute::GPUTarget::G510;
    }
    else if (version.find("G310") != std::string::npos)
    {
        return arm_compute::GPUTarget::G310;
    }
    else if (version.find("G715") != std::string::npos)
    {
        return arm_compute::GPUTarget::G715;
    }
    else if (version.find("G615") != std::string::npos)
    {
        return arm_compute::GPUTarget::G615;
    }
    else
    {
        return arm_compute::GPUTarget::UNKNOWN;
    }
}

arm_compute::GPUTarget get_bifrost_target(const std::string &version)
{
    if (version.find("G71") != std::string::npos)
    {
        return arm_compute::GPUTarget::G71;
    }
    else if (version.find("G72") != std::string::npos)
    {
        return arm_compute::GPUTarget::G72;
    }
    else if (version.find("G51BIG") != std::string::npos)
    {
        return arm_compute::GPUTarget::G51BIG;
    }
    else if (version.find("G51LIT") != std::string::npos)
    {
        return arm_compute::GPUTarget::G51LIT;
    }
    else if (version.find("G51") != std::string::npos)
    {
        return arm_compute::GPUTarget::G51;
    }
    else if (version.find("G52LIT") != std::string::npos)
    {
        return arm_compute::GPUTarget::G52LIT;
    }
    else if (version.find("G52") != std::string::npos)
    {
        return arm_compute::GPUTarget::G52;
    }
    else if (version.find("G76") != std::string::npos)
    {
        return arm_compute::GPUTarget::G76;
    }
    else if (version.find("G31") != std::string::npos)
    {
        return arm_compute::GPUTarget::G31;
    }
    else
    {
        return arm_compute::GPUTarget::UNKNOWN;
    }
}

arm_compute::GPUTarget get_midgard_target(const std::string &version)
{
    if (version.find("T600") != std::string::npos)
    {
        return arm_compute::GPUTarget::T600;
    }
    else if (version.find("T700") != std::string::npos)
    {
        return arm_compute::GPUTarget::T700;
    }
    else if (version.find("T800") != std::string::npos)
    {
        return arm_compute::GPUTarget::T800;
    }
    else
    {
        return arm_compute::GPUTarget::MIDGARD;
    }
}
} // namespace

namespace arm_compute
{
const std::string &string_from_target(GPUTarget target)
{
    static std::map<GPUTarget, const std::string> gpu_target_map = {
        {GPUTarget::MIDGARD, "midgard"}, {GPUTarget::BIFROST, "bifrost"}, {GPUTarget::VALHALL, "valhall"},
        {GPUTarget::T600, "t600"},       {GPUTarget::T700, "t700"},       {GPUTarget::T800, "t800"},
        {GPUTarget::G71, "g71"},         {GPUTarget::G72, "g72"},         {GPUTarget::G51, "g51"},
        {GPUTarget::G51BIG, "g51big"},   {GPUTarget::G51LIT, "g51lit"},   {GPUTarget::G31, "g31"},
        {GPUTarget::G76, "g76"},         {GPUTarget::G52, "g52"},         {GPUTarget::G52LIT, "g52lit"},
        {GPUTarget::G77, "g77"},         {GPUTarget::G57, "g57"},         {GPUTarget::G78, "g78"},
        {GPUTarget::G68, "g68"},         {GPUTarget::G78AE, "g78ae"},     {GPUTarget::G710, "g710"},
        {GPUTarget::G610, "g610"},       {GPUTarget::G510, "g510"},       {GPUTarget::G310, "g310"},
        {GPUTarget::G715, "g715"},       {GPUTarget::G615, "g615"},
    };

    return gpu_target_map[target];
}

GPUTarget get_target_from_name(const std::string &device_name)
{
    std::regex  mali_regex(R"(Mali-(.*))");
    std::smatch name_parts;
    const bool  found_mali = std::regex_search(device_name, name_parts, mali_regex);

    if (!found_mali)
    {
        ARM_COMPUTE_LOG_INFO_MSG_CORE("Can't find valid Arm® Mali™ GPU. Target is set to default.");
        return GPUTarget::MIDGARD;
    }

    const char         target  = name_parts.str(1)[0];
    const std::string &version = name_parts.str(1);

    std::regex future_regex(R"(.*X)");
    const bool is_future_gpu = std::regex_search(version, future_regex);

    // Work-out gpu target
    GPUTarget gpu_target;
    if (target == 'G' || is_future_gpu)
    {
        // Check for Valhall or Bifrost
        gpu_target = get_valhall_target(version);
        if (gpu_target == GPUTarget::UNKNOWN)
        {
            gpu_target = get_bifrost_target(version);
        }

        // Default GPUTarget
        if (gpu_target == GPUTarget::UNKNOWN)
        {
            gpu_target = GPUTarget::VALHALL;
        }
    }
    else if (target == 'T')
    {
        gpu_target = get_midgard_target(version);
    }
    else
    {
        gpu_target = GPUTarget::UNKNOWN;
    }

    // Report in case of unknown target
    if (gpu_target == GPUTarget::UNKNOWN)
    {
        ARM_COMPUTE_LOG_INFO_MSG_CORE("Arm® Mali™ Mali GPU unknown. Target is set to the default one. (BIFROST)");
        return GPUTarget::BIFROST;
    }

    return gpu_target;
}

GPUTarget get_arch_from_target(GPUTarget target)
{
    return (target & GPUTarget::GPU_ARCH_MASK);
}
} // namespace arm_compute
