// 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.

#include "util/url_parser.h"

#include <ctype.h>
#include <stdint.h>

#include <algorithm>
#include <string>

#include "core/string_ref.h"
#include "util/string_search.hpp"

namespace doris {
const StringRef UrlParser::_s_url_authority("AUTHORITY", 9);
const StringRef UrlParser::_s_url_file("FILE", 4);
const StringRef UrlParser::_s_url_host("HOST", 4);
const StringRef UrlParser::_s_url_path("PATH", 4);
const StringRef UrlParser::_s_url_protocol("PROTOCOL", 8);
const StringRef UrlParser::_s_url_query("QUERY", 5);
const StringRef UrlParser::_s_url_ref("REF", 3);
const StringRef UrlParser::_s_url_userinfo("USERINFO", 8);
const StringRef UrlParser::_s_url_port("PORT", 4);
const StringRef UrlParser::_s_protocol("://", 3);
const StringRef UrlParser::_s_at("@", 1);
const StringRef UrlParser::_s_slash("/", 1);
const StringRef UrlParser::_s_colon(":", 1);
const StringRef UrlParser::_s_question("?", 1);
const StringRef UrlParser::_s_hash("#", 1);
const StringSearch UrlParser::_s_protocol_search(&_s_protocol);
const StringSearch UrlParser::_s_at_search(&_s_at);
const StringSearch UrlParser::_s_slash_search(&_s_slash);
const StringSearch UrlParser::_s_colon_search(&_s_colon);
const StringSearch UrlParser::_s_question_search(&_s_question);
const StringSearch UrlParser::_s_hash_search(&_s_hash);

bool UrlParser::parse_url(const StringRef& url, UrlPart part, StringRef* result) {
    result->data = nullptr;
    result->size = 0;
    // Remove leading and trailing spaces.
    StringRef trimmed_url = url.trim();

    // All parts require checking for the _s_protocol.
    int32_t protocol_pos = _s_protocol_search.search(&trimmed_url);
    if (protocol_pos < 0) {
        return false;
    }

    // Positioned to first char after '://'.
    StringRef protocol_end = trimmed_url.substring(protocol_pos + _s_protocol.size);

    switch (part) {
    case AUTHORITY: {
        // Find first '/'.
        int32_t end_pos = _s_slash_search.search(&protocol_end);
        *result = protocol_end.substring(0, end_pos);
        break;
    }

    case FILE:
    case PATH: {
        // Find first '/'.
        int32_t start_pos = _s_slash_search.search(&protocol_end);

        if (start_pos < 0) {
            // Return empty string. This is what Hive does.
            return true;
        }

        StringRef path_start = protocol_end.substring(start_pos);
        int32_t end_pos;

        if (part == FILE) {
            // End _s_at '#'.
            end_pos = _s_hash_search.search(&path_start);
        } else {
            // End string _s_at next '?' or '#'.
            end_pos = _s_question_search.search(&path_start);

            if (end_pos < 0) {
                // No '?' was found, look for '#'.
                end_pos = _s_hash_search.search(&path_start);
            }
        }

        *result = path_start.substring(0, end_pos);
        break;
    }

    case HOST: {
        // Find '@'.
        int32_t start_pos = _s_at_search.search(&protocol_end);

        if (start_pos < 0) {
            // No '@' was found, i.e., no user:pass info was given, start after _s_protocol.
            start_pos = 0;
        } else {
            // Skip '@'.
            start_pos += _s_at.size;
        }

        StringRef host_start = protocol_end.substring(start_pos);
        // Find first '?'.
        int32_t query_start_pos = _s_question_search.search(&host_start);
        if (query_start_pos > 0) {
            host_start = host_start.substring(0, query_start_pos);
        }
        // Find ':' to strip out port.
        int32_t end_pos = _s_colon_search.search(&host_start);

        if (end_pos < 0) {
            // No port was given. search for '/' to determine ending position.
            end_pos = _s_slash_search.search(&host_start);
        }

        *result = host_start.substring(0, end_pos);
        break;
    }

    case PROTOCOL: {
        *result = trimmed_url.substring(0, protocol_pos);
        break;
    }

    case QUERY: {
        // Find first '?'.
        int32_t start_pos = _s_question_search.search(&protocol_end);

        if (start_pos < 0) {
            // Indicate no query was found.
            return false;
        }

        StringRef query_start = protocol_end.substring(start_pos + _s_question.size);
        // End string _s_at next '#'.
        int32_t end_pos = _s_hash_search.search(&query_start);
        *result = query_start.substring(0, end_pos);
        break;
    }

    case REF: {
        // Find '#'.
        int32_t start_pos = _s_hash_search.search(&protocol_end);

        if (start_pos < 0) {
            // Indicate no user and pass were given.
            return false;
        }

        *result = protocol_end.substring(start_pos + _s_hash.size);
        break;
    }

    case USERINFO: {
        // Find '@'.
        int32_t end_pos = _s_at_search.search(&protocol_end);

        if (end_pos < 0) {
            // Indicate no user and pass were given.
            return false;
        }

        *result = protocol_end.substring(0, end_pos);
        break;
    }

    case PORT: {
        // Find '@'.
        int32_t start_pos = _s_at_search.search(&protocol_end);

        if (start_pos < 0) {
            // No '@' was found, i.e., no user:pass info was given, start after _s_protocol.
            start_pos = 0;
        } else {
            // Skip '@'.
            start_pos += _s_at.size;
        }

        StringRef host_start = protocol_end.substring(start_pos);
        // Find ':' to strip out port.
        int32_t end_pos = _s_colon_search.search(&host_start);
        //no port found
        if (end_pos < 0) {
            return false;
        }

        StringRef port_start_str = host_start.substring(end_pos + _s_colon.size);
        int32_t port_end_pos = _s_slash_search.search(&port_start_str);
        //if '/' not found, try to find '?'
        if (port_end_pos < 0) {
            port_end_pos = _s_question_search.search(&port_start_str);
        }
        *result = port_start_str.substring(0, port_end_pos);
        break;
    }

    case INVALID:
        return false;
    }

    return true;
}

bool UrlParser::parse_url_key(const StringRef& url, UrlPart part, const StringRef& key,
                              StringRef* result) {
    // Part must be query to ask for a specific query key.
    if (part != QUERY) {
        return false;
    }

    // Remove leading and trailing spaces.
    StringRef trimmed_url = url.trim();

    // Search for the key in the url, ignoring malformed URLs for now.
    StringSearch key_search(&key);

    while (trimmed_url.size > 0) {
        // Search for the key in the current substring.
        int32_t key_pos = key_search.search(&trimmed_url);
        bool match = true;

        if (key_pos < 0) {
            return false;
        }

        // Key pos must be != 0 because it must be preceded by a '?' or a '&'.
        // Check that the char before key_pos is either '?' or '&'.
        if (key_pos == 0 ||
            (trimmed_url.data[key_pos - 1] != '?' && trimmed_url.data[key_pos - 1] != '&')) {
            match = false;
        }

        // Advance substring beyond matching key.
        trimmed_url = trimmed_url.substring(key_pos + key.size);

        if (!match) {
            continue;
        }

        if (trimmed_url.size <= 0) {
            break;
        }

        // Next character must be '=', otherwise the match cannot be a key in the query part.
        if (trimmed_url.data[0] != '=') {
            continue;
        }

        int32_t pos = 1;

        // Find ending position of key's value by matching '#' or '&'.
        while (pos < trimmed_url.size) {
            switch (trimmed_url.data[pos]) {
            case '#':
            case '&':
                *result = trimmed_url.substring(1, pos - 1);
                return true;
            }

            ++pos;
        }

        // Ending position is end of string.
        *result = trimmed_url.substring(1);
        return true;
    }

    return false;
}

UrlParser::UrlPart UrlParser::get_url_part(const StringRef& part) {
    // Quick filter on requested URL part, based on first character.
    // Hive requires the requested URL part to be all upper case.
    std::string part_str = part.to_string();
    transform(part_str.begin(), part_str.end(), part_str.begin(), ::toupper);
    StringRef newPart = StringRef(part_str);
    switch (newPart.data[0]) {
    case 'A': {
        if (!newPart.eq(_s_url_authority)) {
            return INVALID;
        }

        return AUTHORITY;
    }

    case 'F': {
        if (!newPart.eq(_s_url_file)) {
            return INVALID;
        }

        return FILE;
    }

    case 'H': {
        if (!newPart.eq(_s_url_host)) {
            return INVALID;
        }

        return HOST;
    }

    case 'P': {
        if (newPart.eq(_s_url_path)) {
            return PATH;
        } else if (newPart.eq(_s_url_protocol)) {
            return PROTOCOL;
        } else if (newPart.eq(_s_url_port)) {
            return PORT;
        } else {
            return INVALID;
        }
    }

    case 'Q': {
        if (!newPart.eq(_s_url_query)) {
            return INVALID;
        }

        return QUERY;
    }

    case 'R': {
        if (!newPart.eq(_s_url_ref)) {
            return INVALID;
        }

        return REF;
    }

    case 'U': {
        if (!newPart.eq(_s_url_userinfo)) {
            return INVALID;
        }

        return USERINFO;
    }

    default:
        return INVALID;
    }
}

StringRef UrlParser::extract_url(StringRef url, StringRef name) {
    StringRef result("", 0);
    // Remove leading and trailing spaces.
    StringRef trimmed_url = url.trim();
    // find '?'
    int32_t question_pos = _s_question_search.search(&trimmed_url);
    if (question_pos < 0) {
        // this url no parameters.
        // Example: https://doris.apache.org/
        return result;
    }

    // find '#'
    int32_t hash_pos = _s_hash_search.search(&trimmed_url);
    StringRef sub_url;
    if (hash_pos < 0) {
        sub_url = trimmed_url.substring(question_pos + 1, trimmed_url.size - question_pos - 1);
    } else {
        sub_url = trimmed_url.substring(question_pos + 1, hash_pos - question_pos - 1);
    }

    // find '&' and '=', and extract target parameter
    // Example: k1=aa&k2=bb&k3=cc&test=dd
    int64_t and_pod;
    auto len = sub_url.size;
    StringRef key_url;
    while (true) {
        if (len <= 0) {
            break;
        }
        and_pod = sub_url.find_first_of('&');
        if (and_pod != -1) {
            key_url = sub_url.substring(0, and_pod);
            sub_url = sub_url.substring(and_pod + 1, len - and_pod - 1);
        } else {
            auto end_pos = sub_url.find_first_of('#');
            key_url = end_pos == -1 ? sub_url : sub_url.substring(0, end_pos);
            sub_url = result;
        }
        len = sub_url.size;

        auto eq_pod = key_url.find_first_of('=');
        if (eq_pod == -1) {
            // invalid url. like: k1&k2=bb
            continue;
        }
        auto key_len = key_url.size;
        auto key = key_url.substring(0, eq_pod);
        if (name == key) {
            return key_url.substring(eq_pod + 1, key_len - eq_pod - 1);
        }
    }
    return result;
}
} // namespace doris
