/*******************************************************************************
 * 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.olingo.odata2.jpa.processor.core.callback;

import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.olingo.odata2.api.ODataCallback;
import org.apache.olingo.odata2.api.edm.EdmEntitySet;
import org.apache.olingo.odata2.api.edm.EdmEntityType;
import org.apache.olingo.odata2.api.edm.EdmException;
import org.apache.olingo.odata2.api.edm.EdmNavigationProperty;
import org.apache.olingo.odata2.api.edm.EdmProperty;
import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties;
import org.apache.olingo.odata2.api.ep.EntityProviderWriteProperties.ODataEntityProviderPropertiesBuilder;
import org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent;
import org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent;
import org.apache.olingo.odata2.api.ep.callback.WriteCallbackContext;
import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackContext;
import org.apache.olingo.odata2.api.ep.callback.WriteEntryCallbackResult;
import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackContext;
import org.apache.olingo.odata2.api.ep.callback.WriteFeedCallbackResult;
import org.apache.olingo.odata2.api.exception.ODataApplicationException;
import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode;
import org.apache.olingo.odata2.api.uri.NavigationPropertySegment;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAEntityParser;

public class JPAExpandCallBack implements OnWriteFeedContent, OnWriteEntryContent, ODataCallback {

  private URI baseUri;
  private List<ArrayList<NavigationPropertySegment>> expandList;
  private EdmEntitySet nextEntitySet = null;
  private HashMap<String, List<EdmProperty>> edmPropertyMap = new HashMap<String, List<EdmProperty>>();

  private JPAExpandCallBack(final URI baseUri, final List<ArrayList<NavigationPropertySegment>> expandList) {
    super();
    this.baseUri = baseUri;
    this.expandList = expandList;
  }

  @Override
  public WriteEntryCallbackResult retrieveEntryResult(final WriteEntryCallbackContext context)
      throws ODataApplicationException {
    WriteEntryCallbackResult result = new WriteEntryCallbackResult();
    Map<String, Object> entry = context.getEntryData();
    Map<String, Object> edmPropertyValueMap = null;
    List<EdmNavigationProperty> currentNavPropertyList = null;
    Map<String, ExpandSelectTreeNode> navigationLinks = null;
    JPAEntityParser jpaResultParser = new JPAEntityParser();
    EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty();
    try {
      Object inlinedEntry = entry.get(currentNavigationProperty.getName());
      if (nextEntitySet == null) {
        nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty);
      }
      edmPropertyValueMap = jpaResultParser.parse2EdmPropertyValueMap(inlinedEntry, nextEntitySet.getEntityType());
      result.setEntryData(edmPropertyValueMap);
      navigationLinks = context.getCurrentExpandSelectTreeNode().getLinks();
      if (navigationLinks.size() > 0) {
        currentNavPropertyList = new ArrayList<EdmNavigationProperty>();
        List<EdmNavigationProperty> nextNavProperty =
            getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty());
        if (nextNavProperty != null) {
          currentNavPropertyList.addAll(nextNavProperty);
        }
        HashMap<String, Object> navigationMap =
            jpaResultParser.parse2EdmNavigationValueMap(inlinedEntry, currentNavPropertyList);
        if (edmPropertyValueMap != null) {
          edmPropertyValueMap.putAll(navigationMap);
        }
        result.setEntryData(edmPropertyValueMap);
      }
      result.setInlineProperties(getInlineEntityProviderProperties(context));
    } catch (EdmException e) {
      throw new ODataApplicationException(e.getMessage(), Locale.getDefault(), e);
    } catch (ODataJPARuntimeException e) {
      throw new ODataApplicationException(e.getMessage(), Locale.getDefault(), e);
    }

    return result;
  }

  private List<EdmProperty> getEdmProperties(final EdmEntitySet entitySet, final ExpandSelectTreeNode expandTreeNode)
      throws ODataApplicationException {

    try {
      String name = entitySet.getName();
      if (edmPropertyMap.containsKey(name)) {
        return edmPropertyMap.get(name);
      }
      List<EdmProperty> edmProperties = new ArrayList<EdmProperty>();
      edmProperties.addAll(expandTreeNode.getProperties());
      boolean hit = false;
      for (EdmProperty keyProperty : entitySet.getEntityType().getKeyProperties()) {
        hit = false;
        for (EdmProperty property : edmProperties) {
          if (property.getName().equals(keyProperty.getName())) {
            hit = true;
            break;
          }
        }
        if (hit == false) {
          edmProperties.add(keyProperty);
        }
      }
      edmPropertyMap.put(name, edmProperties);
      return edmProperties;
    } catch (EdmException e) {
      throw new ODataApplicationException(e.getMessage(), Locale.getDefault(), e);
    }
  }

  @Override
  public WriteFeedCallbackResult retrieveFeedResult(final WriteFeedCallbackContext context)
      throws ODataApplicationException {
    WriteFeedCallbackResult result = new WriteFeedCallbackResult();
    HashMap<String, Object> inlinedEntry = (HashMap<String, Object>) context.getEntryData();
    List<Map<String, Object>> edmEntityList = new ArrayList<Map<String, Object>>();
    JPAEntityParser jpaResultParser = new JPAEntityParser();
    List<EdmNavigationProperty> currentNavPropertyList = null;
    EdmNavigationProperty currentNavigationProperty = context.getNavigationProperty();
    ExpandSelectTreeNode currentExpandTreeNode = context.getCurrentExpandSelectTreeNode();

    try {
      @SuppressWarnings({ "unchecked" })
      Collection<Object> listOfItems = (Collection<Object>) inlinedEntry.get(context.getNavigationProperty().getName());
      if (nextEntitySet == null) {
        nextEntitySet = context.getSourceEntitySet().getRelatedEntitySet(currentNavigationProperty);
      }
      if (currentExpandTreeNode.getProperties().size() > 0) {
        edmEntityList =
            jpaResultParser.parse2EdmEntityList(listOfItems, getEdmProperties(nextEntitySet,
                currentExpandTreeNode));
      } else {
        edmEntityList = jpaResultParser.parse2EdmEntityList(listOfItems, nextEntitySet.getEntityType());
      }
      result.setFeedData(edmEntityList);

      if (currentExpandTreeNode.getLinks().size() > 0) {
        currentNavPropertyList = new ArrayList<EdmNavigationProperty>();
        List<EdmNavigationProperty> nextNavPropertyList =
            getNextNavigationProperty(context.getSourceEntitySet().getEntityType(), context.getNavigationProperty());
        if (nextNavPropertyList != null) {
          currentNavPropertyList.addAll(nextNavPropertyList);
        }
        int count = 0;
        for (Object object : listOfItems) {
          HashMap<String, Object> navigationMap =
              jpaResultParser.parse2EdmNavigationValueMap(object, currentNavPropertyList);
          edmEntityList.get(count).putAll(navigationMap);
          count++;
        }
        result.setFeedData(edmEntityList);
      }
      result.setInlineProperties(getInlineEntityProviderProperties(context));
    } catch (EdmException e) {
      throw new ODataApplicationException(e.getMessage(), Locale.getDefault(), e);
    } catch (ODataJPARuntimeException e) {
      throw new ODataApplicationException(e.getMessage(), Locale.getDefault(), e);
    }
    return result;
  }

  private List<EdmNavigationProperty> getNextNavigationProperty(final EdmEntityType sourceEntityType,
      final EdmNavigationProperty navigationProperty) throws EdmException {
    final List<EdmNavigationProperty> edmNavigationPropertyList = new ArrayList<EdmNavigationProperty>();
    for (ArrayList<NavigationPropertySegment> navPropSegments : expandList) {
      int size = navPropSegments.size();
      for (int i = 0; i < size; i++) {
        EdmNavigationProperty navProperty = navPropSegments.get(i).getNavigationProperty();
        if (testNavPropertySegment(navProperty, sourceEntityType, navigationProperty)) {
          if (i < size - 1) {
            edmNavigationPropertyList.add(navPropSegments.get(i + 1).getNavigationProperty());
          }
        }
      }
    }
    return edmNavigationPropertyList;
  }

  private boolean testNavPropertySegment(
		  final EdmNavigationProperty navProperty,
		  final EdmEntityType sourceEntityType,
		  final EdmNavigationProperty navigationProperty) throws EdmException {
	  if(navigationProperty.getFromRole().toLowerCase(Locale.ENGLISH).startsWith(
        sourceEntityType.getName().toLowerCase(Locale.ENGLISH))) {
		  final String roleNum = 
				  navigationProperty.getFromRole().substring(sourceEntityType.getName().length());
		  if(roleNum.length() > 0) {
			  try {
				  Integer.parseInt(roleNum);
			  } catch (NumberFormatException e) {
				  return false;
			  }
		  }
	  }
	  return navProperty.getName().equals(navigationProperty.getName());
  }
  
  public static Map<String, ODataCallback> getCallbacks(final URI baseUri,
      final ExpandSelectTreeNode expandSelectTreeNode, final List<ArrayList<NavigationPropertySegment>> expandList)
      throws EdmException {
    Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();

    for (String navigationPropertyName : expandSelectTreeNode.getLinks().keySet()) {
      callbacks.put(navigationPropertyName, new JPAExpandCallBack(baseUri, expandList));
    }

    return callbacks;

  }

  private EntityProviderWriteProperties getInlineEntityProviderProperties(final WriteCallbackContext context)
      throws EdmException {
    ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(baseUri);
    propertiesBuilder.callbacks(getCallbacks(baseUri, context.getCurrentExpandSelectTreeNode(), expandList));
    propertiesBuilder.expandSelectTree(context.getCurrentExpandSelectTreeNode());
    return propertiesBuilder.build();
  }

}
