/**
 * 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.hcatalog.data;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.hadoop.hive.serde2.SerDeException;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.typeinfo.ListTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.MapTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ObjectInspectorFactory for HCatRecordObjectInspectors (and associated helper inspectors)
 */
public class HCatRecordObjectInspectorFactory {

  private final static Logger LOG = LoggerFactory.getLogger(HCatRecordObjectInspectorFactory.class);

  static HashMap<TypeInfo, HCatRecordObjectInspector> cachedHCatRecordObjectInspectors =
      new HashMap<TypeInfo, HCatRecordObjectInspector>();
  static HashMap<TypeInfo, ObjectInspector> cachedObjectInspectors =
      new HashMap<TypeInfo, ObjectInspector>();

  /**
   * Returns HCatRecordObjectInspector given a StructTypeInfo type definition for the record to look into
   * @param typeInfo Type definition for the record to look into
   * @return appropriate HCatRecordObjectInspector
   * @throws SerDeException
   */
  public static HCatRecordObjectInspector getHCatRecordObjectInspector(
      StructTypeInfo typeInfo) throws SerDeException {
    HCatRecordObjectInspector oi = cachedHCatRecordObjectInspectors.get(typeInfo);
    if (oi == null) {

      LOG.debug("Got asked for OI for {} [{} ]",typeInfo.getCategory(),typeInfo.getTypeName());
      switch (typeInfo.getCategory()) {
      case STRUCT :
        StructTypeInfo structTypeInfo = (StructTypeInfo) typeInfo;
        List<String> fieldNames = structTypeInfo.getAllStructFieldNames();
        List<TypeInfo> fieldTypeInfos = structTypeInfo.getAllStructFieldTypeInfos();
        List<ObjectInspector> fieldObjectInspectors = new ArrayList<ObjectInspector>(fieldTypeInfos.size());
        for (int i = 0; i < fieldTypeInfos.size(); i++) {
          fieldObjectInspectors.add(getStandardObjectInspectorFromTypeInfo(fieldTypeInfos.get(i)));
        }
        oi = new HCatRecordObjectInspector(fieldNames,fieldObjectInspectors);

        break;
      default:
        // Hmm.. not good,
        // the only type expected here is STRUCT, which maps to HCatRecord
        // - anything else is an error. Return null as the inspector.
        throw new SerDeException("TypeInfo ["+typeInfo.getTypeName()
            + "] was not of struct type - HCatRecord expected struct type, got ["
            + typeInfo.getCategory().toString()+"]");
      }
      cachedHCatRecordObjectInspectors.put(typeInfo, oi);
    }
    return oi;
  }

  public static ObjectInspector getStandardObjectInspectorFromTypeInfo(TypeInfo typeInfo) {


    ObjectInspector oi = cachedObjectInspectors.get(typeInfo);
    if (oi == null){

      LOG.debug("Got asked for OI for {}, [{}]",typeInfo.getCategory(), typeInfo.getTypeName());
      switch (typeInfo.getCategory()) {
      case PRIMITIVE:
        oi = PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(
            ((PrimitiveTypeInfo) typeInfo).getPrimitiveCategory());
        break;
      case STRUCT:
        StructTypeInfo structTypeInfo = (StructTypeInfo) typeInfo;
        List<String> fieldNames = structTypeInfo.getAllStructFieldNames();
        List<TypeInfo> fieldTypeInfos = structTypeInfo.getAllStructFieldTypeInfos();
        List<ObjectInspector> fieldObjectInspectors =
            new ArrayList<ObjectInspector>(fieldTypeInfos.size());
        for (int i = 0; i < fieldTypeInfos.size(); i++) {
          fieldObjectInspectors.add(getStandardObjectInspectorFromTypeInfo(fieldTypeInfos.get(i)));
        }
        oi = ObjectInspectorFactory.getStandardStructObjectInspector(
            fieldNames, fieldObjectInspectors
            );
        break;
      case LIST:
        ObjectInspector elementObjectInspector = getStandardObjectInspectorFromTypeInfo(
            ((ListTypeInfo)typeInfo).getListElementTypeInfo());
        oi = ObjectInspectorFactory.getStandardListObjectInspector(elementObjectInspector);
        break;
      case MAP:
        ObjectInspector keyObjectInspector = getStandardObjectInspectorFromTypeInfo(
            ((MapTypeInfo)typeInfo).getMapKeyTypeInfo());
        ObjectInspector valueObjectInspector = getStandardObjectInspectorFromTypeInfo(
            ((MapTypeInfo)typeInfo).getMapValueTypeInfo());
        oi = ObjectInspectorFactory.getStandardMapObjectInspector(keyObjectInspector,valueObjectInspector);
        break;
      default:
        oi = null;
      }
      cachedObjectInspectors.put(typeInfo, oi);
    }
    return oi;
  }


}
