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

package org.apache.pig.builtin;

import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.math.BigDecimal;
import java.math.RoundingMode;

import org.apache.pig.EvalFunc;
import org.apache.pig.FuncSpec;
import org.apache.pig.data.Tuple;
import org.apache.pig.impl.logicalLayer.schema.Schema;
import org.apache.pig.data.DataType;
import org.apache.pig.impl.logicalLayer.FrontendException;

/**
 * ROUND_TO safely rounds a number to a given precision by using an intermediate
 * BigDecimal. The too-often seen trick of doing (1000.0 * ROUND(x/1000)) is not
 * only hard to read but also fails to produce numerically accurate results.
 *
 * Given a single data atom and number of digits, it returns a double extending to the
 * given number of decimal places.
 *
 * The result is a multiple of ten to the power given by the digits argument: a
 * negative value zeros out correspondingly many places to the left of the
 * decimal point: ROUND_TO(0.9876543, 3) is 0.988; ROUND_TO(0.9876543, 0) is
 * 1.0; and ROUND_TO(1234.56, -2) is 1200.0.
 *
 * The optional mode argument specifies the {@link java.math.RoundingMode rounding mode};
 * by default, {@link java.math.RoundingMode#HALF_EVEN 'HALF_EVEN'} is used.
 *
 */
public class DoubleRoundTo extends EvalFunc<Double>{
    /**
     * java level API
     * @param input expects a numeric value to round, a number of digits to keep, and an optional rounding mode.
     * @return output returns a single numeric value, the number with only those digits retained
     */
    @Override
    public Double exec(Tuple input) throws IOException {
        if (input == null || input.size() < 2)
            return null;

        try {
            Double       num    = (Double)input.get(0);
            Integer      digits = (Integer)input.get(1);
            RoundingMode mode   = (input.size() >= 3) ?
                RoundingMode.valueOf(DataType.toInteger(input.get(2))) : RoundingMode.HALF_EVEN;
            if (num == null) return null;

            BigDecimal bdnum  = BigDecimal.valueOf(num);
            bdnum = bdnum.setScale(digits, mode);
            return bdnum.doubleValue();
        } catch (Exception e){
            throw new IOException("Caught exception processing input row ", e);
        }
    }

    /* (non-Javadoc)
     * @see org.apache.pig.EvalFunc#getArgToFuncMapping()
     */
    @Override
    public List<FuncSpec> getArgToFuncMapping() throws FrontendException {
        List<FuncSpec> funcList = new ArrayList<FuncSpec>();

        Schema s_dbl_2 = new Schema();
        s_dbl_2.add(new Schema.FieldSchema(null, DataType.DOUBLE));
        s_dbl_2.add(new Schema.FieldSchema(null, DataType.INTEGER));

        Schema s_dbl_3 = new Schema();
        s_dbl_3.add(new Schema.FieldSchema(null, DataType.DOUBLE));
        s_dbl_3.add(new Schema.FieldSchema(null, DataType.INTEGER));
        s_dbl_3.add(new Schema.FieldSchema(null, DataType.INTEGER));

        funcList.add(new FuncSpec(this.getClass().getName(), s_dbl_2));
        funcList.add(new FuncSpec(this.getClass().getName(), s_dbl_3));

        return funcList;
    }

    @Override
    public boolean allowCompileTimeCalculation() {
        return true;
    }
}
