// 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 "exprs/function/round.h"

#include "exprs/function/simple_function_factory.h"

namespace doris {

// We split round funcs from register_function_math() in math.cpp to here,
// so that to speed up compile time and make code more readable.
void register_function_round(SimpleFunctionFactory& factory) {
#define REGISTER_ROUND_FUNCTIONS(IMPL)                                                           \
    factory.register_function<                                                                   \
            FunctionRounding<IMPL<TruncateName>, RoundingMode::Trunc, TieBreakingMode::Auto>>(); \
    factory.register_function<                                                                   \
            FunctionRounding<IMPL<FloorName>, RoundingMode::Floor, TieBreakingMode::Auto>>();    \
    factory.register_function<                                                                   \
            FunctionRounding<IMPL<RoundName>, RoundingMode::Round, TieBreakingMode::Auto>>();    \
    factory.register_function<                                                                   \
            FunctionRounding<IMPL<CeilName>, RoundingMode::Ceil, TieBreakingMode::Auto>>();      \
    factory.register_function<FunctionRounding<IMPL<RoundBankersName>, RoundingMode::Round,      \
                                               TieBreakingMode::Bankers>>();
    REGISTER_ROUND_FUNCTIONS(DoubleRoundOneImpl)
    REGISTER_ROUND_FUNCTIONS(DoubleRoundTwoImpl)
#undef REGISTER_ROUND_FUNCTIONS

#define REGISTER_ROUND_FUNCTIONS_IMPL(IMPL, TYPE)                                                 \
    factory.register_function<FunctionRounding<IMPL<TruncateName, TYPE>, RoundingMode::Trunc,     \
                                               TieBreakingMode::Auto>>();                         \
    factory.register_function<FunctionRounding<IMPL<FloorName, TYPE>, RoundingMode::Floor,        \
                                               TieBreakingMode::Auto>>();                         \
    factory.register_function<FunctionRounding<IMPL<RoundName, TYPE>, RoundingMode::Round,        \
                                               TieBreakingMode::Auto>>();                         \
    factory.register_function<                                                                    \
            FunctionRounding<IMPL<CeilName, TYPE>, RoundingMode::Ceil, TieBreakingMode::Auto>>(); \
    factory.register_function<FunctionRounding<IMPL<RoundBankersName, TYPE>, RoundingMode::Round, \
                                               TieBreakingMode::Bankers>>();

#define REGISTER_ROUND_FUNCTIONS(IMPL)                    \
    REGISTER_ROUND_FUNCTIONS_IMPL(IMPL, TYPE_DECIMAL32)   \
    REGISTER_ROUND_FUNCTIONS_IMPL(IMPL, TYPE_DECIMAL64)   \
    REGISTER_ROUND_FUNCTIONS_IMPL(IMPL, TYPE_DECIMAL128I) \
    REGISTER_ROUND_FUNCTIONS_IMPL(IMPL, TYPE_DECIMAL256)
    REGISTER_ROUND_FUNCTIONS(DecimalRoundOneImpl)
    REGISTER_ROUND_FUNCTIONS(DecimalRoundTwoImpl)
#undef REGISTER_ROUND_FUNCTIONS
#undef REGISTER_ROUND_FUNCTIONS_IMPL

    factory.register_alias("ceil", "dceil");
    factory.register_alias("ceil", "ceiling");
    factory.register_alias("floor", "dfloor");
    factory.register_alias("round", "dround");
}

} // namespace doris
