// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
// This file is copied from
// https://github.com/apache/impala/blob/branch-2.9.0/be/src/util/parse-util.cc
// and modified by Doris

#include "util/parse_util.h"

#include "util/string_parser.hpp"

namespace doris {
#include "common/compile_check_begin.h"
int64_t ParseUtil::parse_mem_spec(const std::string& mem_spec_str, int64_t parent_limit,
                                  int64_t physical_mem, bool* is_percent) {
    if (mem_spec_str.empty()) {
        return 0;
    }

    // Assume last character indicates unit or percent.
    auto number_str_len = mem_spec_str.size() - 1;
    *is_percent = false;
    int64_t multiplier = -1;

    // Look for accepted suffix character.
    switch (*mem_spec_str.rbegin()) {
    case 't':
    case 'T':
        // Terabytes.
        multiplier = 1024L * 1024L * 1024L * 1024L;
        break;
    case 'g':
    case 'G':
        // Gigabytes.
        multiplier = 1024L * 1024L * 1024L;
        break;
    case 'm':
    case 'M':
        // Megabytes.
        multiplier = 1024L * 1024L;
        break;
    case 'k':
    case 'K':
        // Kilobytes
        multiplier = 1024L;
        break;
    case 'b':
    case 'B':
        break;
    case '%':
        *is_percent = true;
        break;
    default:
        // No unit was given. Default to bytes.
        number_str_len = (int)mem_spec_str.size();
        break;
    }

    StringParser::ParseResult result;
    int64_t bytes = -1;

    if (multiplier != -1 || *is_percent) {
        // Parse float - MB or GB or percent
        double limit_val =
                StringParser::string_to_float<double>(mem_spec_str.data(), number_str_len, &result);

        if (result != StringParser::PARSE_SUCCESS) {
            return -1;
        }

        if (multiplier != -1) {
            bytes = int64_t((double)multiplier * limit_val);
        } else if (*is_percent) {
            if (parent_limit == -1) {
                bytes = int64_t(limit_val / 100.0 * (double)physical_mem);
            } else {
                bytes = int64_t(limit_val / 100.0 * (double)parent_limit);
            }
        }
    } else {
        // Parse int - bytes
        int64_t limit_val =
                StringParser::string_to_int<int64_t>(mem_spec_str.data(), number_str_len, &result);

        if (result != StringParser::PARSE_SUCCESS) {
            return -1;
        }

        auto limit_val_double =
                StringParser::string_to_float<double>(mem_spec_str.data(), number_str_len, &result);
        if (result == StringParser::PARSE_SUCCESS && limit_val_double != (double)limit_val) {
            return -1; // mem_spec_str is double.
        }

        bytes = limit_val;
    }

    // Accept -1 as indicator for infinite memory that we report by a 0 return value.
    if (bytes == -1) {
        return 0;
    }
    return bytes;
}

} // namespace doris
