/*
 * 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 "SparkFunctionGetJsonObject.h"
#include <Functions/FunctionFactory.h>


namespace local_engine
{

std::pair<DB::TokenType, StringRef> JSONPathNormalizer::prevToken(DB::IParser::Pos & iter, size_t n)
{
    size_t i = 0;
    for (; i < n && iter->type != DB::TokenType::DollarSign; ++i)
    {
        --iter;
    }
    std::pair<DB::TokenType, StringRef> res = {iter->type, StringRef(iter->begin, iter->end - iter->begin)};
    for (; i > 0; --i)
    {
        ++iter;
    }
    return res;
}

std::pair<DB::TokenType, StringRef> JSONPathNormalizer::nextToken(DB::IParser::Pos & iter, size_t n)
{
    size_t i = 0;
    for (; i < n && iter->type != DB::TokenType::EndOfStream; ++i)
    {
        ++iter;
    }
    std::pair<DB::TokenType, StringRef> res = {iter->type, StringRef(iter->begin, iter->end - iter->begin)};
    for (; i > 0; --i)
    {
        --iter;
    }
    return res;
}

bool JSONPathNormalizer::isSubPathBegin(DB::IParser::Pos & iter)
{
    if (iter->type == DB::TokenType::Dot || (iter->type == DB::TokenType::Number && *iter->begin == '.'))
    {
        return true;
    }
    return false;
}


void JSONPathNormalizer::normalizeOnNumber(DB::IParser::Pos & iter, String & res)
{
    if (*iter->begin == '.')
    {
        res += ".\"";
        res += String(iter->begin + 1, iter->end);
        ++iter;
        auto token_type = iter->type;
        while (token_type != DB::TokenType::Dot && token_type != DB::TokenType::OpeningSquareBracket
               && token_type != DB::TokenType::EndOfStream)
        {
            auto [_, prev_iter_str] = prevToken(iter);
            // may contains spaces
            if (prev_iter_str.data + prev_iter_str.size != iter->begin)
            {
                res += String(prev_iter_str.data + prev_iter_str.size, iter->begin);
            }
            res += String(iter->begin, iter->end);
            ++iter;
            token_type = iter->type;
        }
        auto [_, prev_iter_str] = prevToken(iter);
        res += String(prev_iter_str.data + prev_iter_str.size, iter->begin);
        res += "\"";
    }
    else
        normalizeOnOtherTokens(iter, res);
}

void JSONPathNormalizer::normalizeOnBareWord(DB::IParser::Pos & iter, String & res)
{
    auto [prev_iter_type_2, _] = nextToken(iter);
    /// e.g. $.data.forecast[?(@.aqi>65)]
    if (prev_iter_type_2 == DB::TokenType::At)
    {
        normalizeOnOtherTokens(iter, res);
    }
    else
    {
        auto token_type = iter->type;
        res += "\"";
        size_t i = 0;
        while (token_type != DB::TokenType::Dot && token_type != DB::TokenType::OpeningSquareBracket
               && token_type != DB::TokenType::EndOfStream)
        {
            if (i)
            {
                auto [_, prev_iter_str] = prevToken(iter);
                // may contains spaces
                if (prev_iter_str.data + prev_iter_str.size != iter->begin)
                {
                    res += String(prev_iter_str.data + prev_iter_str.size, iter->begin);
                }
            }
            res += String(iter->begin, iter->end);
            ++iter;
            i += 1;
            token_type = iter->type;
        }
        auto [_, prev_iter_str] = prevToken(iter);
        res += String(prev_iter_str.data + prev_iter_str.size, iter->begin);
        res += "\"";
    }
}


void JSONPathNormalizer::normalizeOnOtherTokens(DB::IParser::Pos & iter, String & res)
{
    res += String(iter->begin, iter->end);
    ++iter;
}


REGISTER_FUNCTION(GetJsonObject)
{
    factory.registerFunction<DB::FunctionSQLJSON<GetJsonObject, GetJsonObjectImpl>>();
}
REGISTER_FUNCTION(FlattenJSONStringOnRequiredFunction)
{
    factory.registerFunction<FlattenJSONStringOnRequiredFunction>();
}
}
