/*
 * 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.hadoop.hive.ql.udf.generic;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils;

/**
 * Abstract GenericUDF for array functions
 */

public abstract class AbstractGenericUDFArrayBase extends GenericUDF {

    static final int ARRAY_IDX = 0;

    private final int minArgCount;
    private final int maxArgCount;
    private final ObjectInspector.Category outputCategory;

    private final String functionName;

    transient ListObjectInspector arrayOI;
    transient ObjectInspector[] argumentOIs;

    transient ObjectInspector arrayElementOI;

    transient Converter converter;

    protected AbstractGenericUDFArrayBase(String functionName, int minArgCount, int maxArgCount, ObjectInspector.Category outputCategory) {
        this.functionName = functionName;
        this.minArgCount = minArgCount;
        this.maxArgCount = maxArgCount;
        this.outputCategory = outputCategory;
    }

    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments)
            throws UDFArgumentException {

        // Check if wrong number of arguments were passed
        checkArgsSize(arguments, minArgCount, maxArgCount);

        // Check if the argument is of category LIST or not
        checkArgCategory(arguments, ARRAY_IDX, ObjectInspector.Category.LIST, functionName,
                org.apache.hadoop.hive.serde.serdeConstants.LIST_TYPE_NAME);

        //return ObjectInspectors based on expected output type
        arrayOI = (ListObjectInspector) arguments[ARRAY_IDX];
        argumentOIs = arguments;
        arrayElementOI = arrayOI.getListElementObjectInspector();
        if (outputCategory == ObjectInspector.Category.LIST) {
            return initListOI(arguments);
        } else {
            return initOI(arguments);
        }
    }

    @Override
    public String getDisplayString(String[] children) {
        return getStandardDisplayString(functionName.toLowerCase(), children);
    }

    void checkArgCategory(ObjectInspector[] arguments, int idx, ObjectInspector.Category category,
                          String functionName, String typeName) throws UDFArgumentTypeException {

        if (!arguments[idx].getCategory().equals(category)) {
            throw new UDFArgumentTypeException(idx,
                    "\"" + typeName + "\" "
                            + "expected at function " + functionName + ", but "
                            + "\"" + arguments[idx].getTypeName() + "\" "
                            + "is found");
        }
    }

    void checkArgIntPrimitiveCategory(PrimitiveObjectInspector objectInspector, String functionName, int idx)
        throws UDFArgumentTypeException {
      switch (objectInspector.getPrimitiveCategory()) {
      case SHORT:
      case INT:
      case LONG:
        break;
      default:
        throw new UDFArgumentTypeException(0,
            "Argument " + idx + " of function " + functionName + " must be \"" + serdeConstants.SMALLINT_TYPE_NAME + "\""
                + " or \"" + serdeConstants.INT_TYPE_NAME + "\"" + " or \"" + serdeConstants.BIGINT_TYPE_NAME
                + "\", but \"" + objectInspector.getTypeName() + "\" was found.");
      }
    }

    ObjectInspector initOI(ObjectInspector[] arguments) {

        GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver =
                new GenericUDFUtils.ReturnObjectInspectorResolver(true);

        ObjectInspector elementObjectInspector =
                ((ListObjectInspector) (arguments[0])).getListElementObjectInspector();

        ObjectInspector returnOI = returnOIResolver.get(elementObjectInspector);
        converter = ObjectInspectorConverters.getConverter(elementObjectInspector, returnOI);
        return returnOI;
    }

    ObjectInspector initListOI(ObjectInspector[] arguments) {
        return ObjectInspectorFactory.getStandardListObjectInspector(initOI(arguments));
    }

    void checkValueAndListElementTypes(ObjectInspector arrayElementOI, String functionName, ObjectInspector valueOI,
        int elementIndex) throws UDFArgumentTypeException {
        // Check if list element and value are of same type
        if (!ObjectInspectorUtils.compareTypes(arrayElementOI, valueOI)) {
            throw new UDFArgumentTypeException(elementIndex,
                String.format("%s type element is expected at function %s(array<%s>,%s), but %s is found",
                    arrayElementOI.getTypeName(), functionName, arrayElementOI.getTypeName(),
                    arrayElementOI.getTypeName(), valueOI.getTypeName()));
        }
    }
}
