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

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.olingo.odata2.api.commons.InlineCount;
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.EdmMapping;
import org.apache.olingo.odata2.api.edm.EdmMultiplicity;
import org.apache.olingo.odata2.api.ep.entry.ODataEntry;
import org.apache.olingo.odata2.api.uri.UriInfo;
import org.apache.olingo.odata2.api.uri.info.DeleteUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntityCountUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntityLinkUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntitySetCountUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntitySetLinksUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntitySetUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetEntityUriInfo;
import org.apache.olingo.odata2.api.uri.info.GetFunctionImportUriInfo;
import org.apache.olingo.odata2.api.uri.info.PostUriInfo;
import org.apache.olingo.odata2.api.uri.info.PutMergePatchUriInfo;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPAContext;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneContext;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPATombstoneEntityListener;
import org.apache.olingo.odata2.jpa.processor.api.ODataJPATransaction;
import org.apache.olingo.odata2.jpa.processor.api.access.JPAFunction;
import org.apache.olingo.odata2.jpa.processor.api.access.JPAMethodContext;
import org.apache.olingo.odata2.jpa.processor.api.access.JPAProcessor;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPAModelException;
import org.apache.olingo.odata2.jpa.processor.api.exception.ODataJPARuntimeException;
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContext;
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLContextType;
import org.apache.olingo.odata2.jpa.processor.api.jpql.JPQLStatement;
import org.apache.olingo.odata2.jpa.processor.api.model.JPAEdmMapping;
import org.apache.olingo.odata2.jpa.processor.core.ODataEntityParser;
import org.apache.olingo.odata2.jpa.processor.core.access.data.JPAPage.JPAPageBuilder;

public class JPAProcessorImpl implements JPAProcessor {

  ODataJPAContext oDataJPAContext;
  EntityManager em;

  public JPAProcessorImpl(final ODataJPAContext oDataJPAContext) {
    this.oDataJPAContext = oDataJPAContext;
    em = oDataJPAContext.getEntityManager();
  }

  /* Process Function Import Request */
  @SuppressWarnings("unchecked")
  @Override
  public List<Object> process(final GetFunctionImportUriInfo uriParserResultView)
      throws ODataJPAModelException, ODataJPARuntimeException {

    JPAMethodContext jpaMethodContext = JPAMethodContext.createBuilder(
        JPQLContextType.FUNCTION, uriParserResultView).build();

    List<Object> resultObj = null;

    try {

      JPAFunction jpaFunction = jpaMethodContext.getJPAFunctionList()
          .get(0);
      Method method = jpaFunction.getFunction();
      Object[] args = jpaFunction.getArguments();

      if (uriParserResultView.getFunctionImport().getReturnType()
          .getMultiplicity().equals(EdmMultiplicity.MANY)) {

        resultObj = (List<Object>) method.invoke(
            jpaMethodContext.getEnclosingObject(), args);
      } else {
        resultObj = new ArrayList<Object>();
        Object result = method.invoke(
            jpaMethodContext.getEnclosingObject(), args);
        resultObj.add(result);
      }

    } catch (EdmException e) {
      throw ODataJPARuntimeException
          .throwException(ODataJPARuntimeException.GENERAL
              .addContent(e.getMessage()), e);
    } catch (IllegalAccessException e) {
      throw ODataJPARuntimeException
          .throwException(ODataJPARuntimeException.GENERAL
              .addContent(e.getMessage()), e);
    } catch (IllegalArgumentException e) {
      throw ODataJPARuntimeException
          .throwException(ODataJPARuntimeException.GENERAL
              .addContent(e.getMessage()), e);
    } catch (InvocationTargetException e) {
      throw ODataJPARuntimeException
          .throwException(ODataJPARuntimeException.GENERAL
              .addContent(e.getTargetException().getMessage()), e.getTargetException());
    }

    return resultObj;
  }

  /* Process Get Entity Set Request (Query) */
  @Override
  public List<Object> process(final GetEntitySetUriInfo uriParserResultView)
      throws ODataJPAModelException, ODataJPARuntimeException {

    if (uriParserResultView.getFunctionImport() != null) {
      return (List<Object>) process((GetFunctionImportUriInfo) uriParserResultView);
    }
    InlineCount inlineCount = uriParserResultView.getInlineCount();
    Integer top = uriParserResultView.getTop() == null ? 1 : uriParserResultView.getTop().intValue();
    boolean hasNoAllPages = inlineCount == null ? true : !inlineCount.equals(InlineCount.ALLPAGES);
    if (top.intValue() == 0 && hasNoAllPages) {
      return new ArrayList<Object>();
    }
    JPQLContextType contextType = null;
    try {
      if (uriParserResultView.getNavigationSegments().size() > 0) {
        contextType = JPQLContextType.JOIN;
      } else {
        contextType = JPQLContextType.SELECT;
      }

      JPQLContext jpqlContext = null;

      if (oDataJPAContext.getPageSize() > 0) {
        jpqlContext = JPQLContext.createBuilder(contextType,
            uriParserResultView, true).build();
      } else {
        jpqlContext = JPQLContext.createBuilder(contextType,
            uriParserResultView).build();
      }

      JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
          .build();
      Map<String, String> customQueryOptions = uriParserResultView.getCustomQueryOptions();
      String deltaToken = null;
      if (customQueryOptions != null) {
        deltaToken = uriParserResultView.getCustomQueryOptions().get("!deltatoken");
      }
      if (deltaToken != null) {
        ODataJPATombstoneContext.setDeltaToken(deltaToken);
      }

      Query query = null;
      List<Object> result = null;

      JPAEdmMapping mapping = (JPAEdmMapping) uriParserResultView.getTargetEntitySet().getEntityType().getMapping();
      ODataJPATombstoneEntityListener listener = null;
      if (mapping.getODataJPATombstoneEntityListener() != null) {
        listener = (ODataJPATombstoneEntityListener) mapping.getODataJPATombstoneEntityListener().newInstance();
        query = listener.getQuery(uriParserResultView, em);
      }
      if (query == null) {
        query = em.createQuery(jpqlStatement.toString());
        if (listener != null) {
          query.getResultList();
          List<Object> deltaResult =
              (List<Object>) ODataJPATombstoneContext.getDeltaResult(((EdmMapping) mapping).getInternalName());
          result = handlePaging(deltaResult, uriParserResultView);
        } else {
          result = handlePaging(query, uriParserResultView);
        }
      } else {
        result = handlePaging(query, uriParserResultView);
      }

      // Set New Token
      if (listener != null) {
        ODataJPATombstoneContext.setDeltaToken(listener.generateDeltaToken((List<Object>) result, query));
      }

      return result == null ? new ArrayList<Object>() : result;

    } catch (Exception e) {
      throw ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);

    }
  }

  /* Process Get Entity Request (Read) */
  @Override
  public <T> Object process(GetEntityUriInfo uriParserResultView)
      throws ODataJPAModelException, ODataJPARuntimeException {

    JPQLContextType contextType = null;
    if (uriParserResultView instanceof GetEntityUriInfo) {
      uriParserResultView = ((GetEntityUriInfo) uriParserResultView);
      if (uriParserResultView.getNavigationSegments().size() > 0) {
        contextType = JPQLContextType.JOIN_SINGLE;
      } else {
        contextType = JPQLContextType.SELECT_SINGLE;
      }
    }

    return readEntity(uriParserResultView, contextType);
  }

  /* Process $count for Get Entity Set Request */
  @Override
  public long process(final GetEntitySetCountUriInfo resultsView)
      throws ODataJPAModelException, ODataJPARuntimeException {

    JPQLContextType contextType = null;
    try {
      if (!resultsView.getStartEntitySet().getName()
          .equals(resultsView.getTargetEntitySet().getName())) {
        contextType = JPQLContextType.JOIN_COUNT;
      } else {
        contextType = JPQLContextType.SELECT_COUNT;
      }
    } catch (EdmException e) {
      ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.GENERAL, e);
    }

    JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
        resultsView).build();

    JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
        .build();
    Query query = null;
    try {

      query = em.createQuery(jpqlStatement.toString());
      List<?> resultList = query.getResultList();
      if (resultList != null && resultList.size() == 1) {
        return Long.valueOf(resultList.get(0).toString());
      }
    } catch (IllegalArgumentException e) {
      throw ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
    }
    return 0;
  }

  /* Process $count for Get Entity Request */
  @Override
  public long process(final GetEntityCountUriInfo resultsView) throws ODataJPAModelException, ODataJPARuntimeException {

    JPQLContextType contextType = null;
    try {
      if (!resultsView.getStartEntitySet().getName()
          .equals(resultsView.getTargetEntitySet().getName())) {
        contextType = JPQLContextType.JOIN_COUNT;
      } else {
        contextType = JPQLContextType.SELECT_COUNT;
      }
    } catch (EdmException e) {
      ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.GENERAL, e);
    }

    JPQLContext jpqlContext = JPQLContext.createBuilder(contextType,
        resultsView).build();

    JPQLStatement jpqlStatement = JPQLStatement.createBuilder(jpqlContext)
        .build();
    Query query = null;
    try {

      query = em.createQuery(jpqlStatement.toString());
      List<?> resultList = query.getResultList();
      if (resultList != null && resultList.size() == 1) {
        return Long.valueOf(resultList.get(0).toString());
      }
    } catch (IllegalArgumentException e) {
      throw ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
    }

    return 0;
  }

  /* Process Create Entity Request */
  @Override
  public Object process(final PostUriInfo createView, final InputStream content,
      final String requestedContentType) throws ODataJPAModelException,
      ODataJPARuntimeException {
    return processCreate(createView, content, null, requestedContentType);
  }

  @Override
  public Object process(final PostUriInfo createView, final Map<String, Object> content)
      throws ODataJPAModelException, ODataJPARuntimeException {
    return processCreate(createView, null, content, null);
  }

  /* Process Update Entity Request */
  @Override
  public Object process(final PutMergePatchUriInfo updateView,
      final InputStream content, final String requestContentType)
      throws ODataJPAModelException, ODataJPARuntimeException {
    return processUpdate(updateView, content, null, requestContentType);
  }

  @Override
  public Object process(final PutMergePatchUriInfo updateView, final Map<String, Object> content)
      throws ODataJPAModelException, ODataJPARuntimeException {
    return processUpdate(updateView, null, content, null);
  }

  /* Process Delete Entity Request */
  @Override
  public Object process(DeleteUriInfo uriParserResultView, final String contentType)
      throws ODataJPAModelException, ODataJPARuntimeException {
    JPQLContextType contextType = null;
    try {
      if (uriParserResultView instanceof DeleteUriInfo) {
        if (((UriInfo) uriParserResultView).isLinks()) {
          return deleteLink(uriParserResultView);
        }
        uriParserResultView = ((DeleteUriInfo) uriParserResultView);
        if (!((DeleteUriInfo) uriParserResultView).getStartEntitySet().getName()
            .equals(((DeleteUriInfo) uriParserResultView).getTargetEntitySet().getName())) {
          contextType = JPQLContextType.JOIN_SINGLE;
        } else {
          contextType = JPQLContextType.SELECT_SINGLE;
        }
      }
    } catch (EdmException e) {
      ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.GENERAL, e);
    }

    Object selectedObject = readEntity(uriParserResultView, contextType);
    if (selectedObject != null) {
      try {
        boolean isLocalTransaction = setTransaction();
        em.remove(selectedObject);
        em.flush();
        if (isLocalTransaction) {
          oDataJPAContext.getODataJpaTransaction().commit();
        }

      } catch (Exception e) {
        throw ODataJPARuntimeException.throwException(
            ODataJPARuntimeException.ERROR_JPQL_DELETE_REQUEST, e);
      }
    }
    return selectedObject;
  }

  /* Process Get Entity Link Request */
  @Override
  public Object process(final GetEntityLinkUriInfo uriParserResultView)
      throws ODataJPAModelException, ODataJPARuntimeException {

    return this.process((GetEntityUriInfo) uriParserResultView);
  }

  /* Process Get Entity Set Link Request */
  @Override
  public List<Object> process(final GetEntitySetLinksUriInfo uriParserResultView)
      throws ODataJPAModelException, ODataJPARuntimeException {
    return this.process((GetEntitySetUriInfo) uriParserResultView);
  }

  @Override
  public void process(final PostUriInfo uriInfo,
      final InputStream content, final String requestContentType, final String contentType)
      throws ODataJPARuntimeException, ODataJPAModelException {
    JPALink link = new JPALink(oDataJPAContext);
    link.create(uriInfo, content, requestContentType, contentType);
    link.save();
  }

  @Override
  public void process(final PutMergePatchUriInfo putUriInfo,
      final InputStream content, final String requestContentType, final String contentType)
      throws ODataJPARuntimeException, ODataJPAModelException {

    JPALink link = new JPALink(oDataJPAContext);
    link.update(putUriInfo, content, requestContentType, contentType);
    link.save();

  }

  /* Common method for Read and Delete */
  private Object readEntity(final Object uriParserResultView, final JPQLContextType contextType)
      throws ODataJPAModelException, ODataJPARuntimeException {

    Object selectedObject = null;

    if (uriParserResultView instanceof DeleteUriInfo || uriParserResultView instanceof GetEntityUriInfo
        || uriParserResultView instanceof PutMergePatchUriInfo) {

      JPQLContext selectJPQLContext = JPQLContext.createBuilder(
          contextType, uriParserResultView).build();

      JPQLStatement selectJPQLStatement = JPQLStatement.createBuilder(
          selectJPQLContext).build();
      Query query = null;
      try {
        query = em.createQuery(selectJPQLStatement.toString());
        if (!query.getResultList().isEmpty()) {
          selectedObject = query.getResultList().get(0);
        }
      } catch (IllegalArgumentException e) {
        throw ODataJPARuntimeException.throwException(
            ODataJPARuntimeException.ERROR_JPQL_QUERY_CREATE, e);
      }
    }
    return selectedObject;
  }

  private Object processCreate(final PostUriInfo createView, final InputStream content,
      final Map<String, Object> properties,
      final String requestedContentType) throws ODataJPAModelException,
      ODataJPARuntimeException {
    try {
      final EdmEntitySet oDataEntitySet = createView.getTargetEntitySet();
      final EdmEntityType oDataEntityType = oDataEntitySet.getEntityType();
      final JPAEntity virtualJPAEntity = new JPAEntity(oDataEntityType, oDataEntitySet, oDataJPAContext);
      Object jpaEntity = null;

      if (content != null) {
        final ODataEntityParser oDataEntityParser = new ODataEntityParser(oDataJPAContext);
        final ODataEntry oDataEntry =
            oDataEntityParser.parseEntry(oDataEntitySet, content, requestedContentType, false);
        virtualJPAEntity.create(oDataEntry);
      } else if (properties != null) {
        virtualJPAEntity.create(properties);
      } else {
        return null;
      }

      boolean isLocalTransaction = setTransaction();
      jpaEntity = virtualJPAEntity.getJPAEntity();

      em.persist(jpaEntity);
      if (em.contains(jpaEntity)) {
        if (isLocalTransaction) {
          oDataJPAContext.getODataJpaTransaction().commit();
        }
        return jpaEntity;
      }
    } catch (Exception e) {
      throw ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.ERROR_JPQL_CREATE_REQUEST, e);
    }
    return null;
  }

  private <T> Object processUpdate(PutMergePatchUriInfo updateView,
      final InputStream content, final Map<String, Object> properties, final String requestContentType)
      throws ODataJPAModelException, ODataJPARuntimeException {
    JPQLContextType contextType = null;
    Object jpaEntity = null;
    try {
      boolean isLocalTransaction = setTransaction();
      if (updateView instanceof PutMergePatchUriInfo) {
        updateView = ((PutMergePatchUriInfo) updateView);
        if (!((PutMergePatchUriInfo) updateView).getStartEntitySet().getName()
            .equals(((PutMergePatchUriInfo) updateView).getTargetEntitySet().getName())) {
          contextType = JPQLContextType.JOIN_SINGLE;
        } else {
          contextType = JPQLContextType.SELECT_SINGLE;
        }
      }

      jpaEntity = readEntity(updateView, contextType);

      if (jpaEntity == null) {
        throw ODataJPARuntimeException
            .throwException(ODataJPARuntimeException.RESOURCE_NOT_FOUND, null);
      }

      final EdmEntitySet oDataEntitySet = updateView.getTargetEntitySet();
      final EdmEntityType oDataEntityType = oDataEntitySet.getEntityType();
      final JPAEntity virtualJPAEntity = new JPAEntity(oDataEntityType, oDataEntitySet, oDataJPAContext);
      virtualJPAEntity.setJPAEntity(jpaEntity);

      if (content != null) {
        final ODataEntityParser oDataEntityParser = new ODataEntityParser(oDataJPAContext);
        final ODataEntry oDataEntry = oDataEntityParser.parseEntry(oDataEntitySet, content, requestContentType, false);
        virtualJPAEntity.update(oDataEntry);
      } else if (properties != null) {
        virtualJPAEntity.update(properties);
      } else {
        return null;
      }
      em.flush();
      if (isLocalTransaction) {
        oDataJPAContext.getODataJpaTransaction().commit();
      }
    } catch (Exception e) {
      throw ODataJPARuntimeException.throwException(
          ODataJPARuntimeException.ERROR_JPQL_UPDATE_REQUEST, e);
    }

    return jpaEntity;
  }

  private Object deleteLink(final DeleteUriInfo uriParserResultView) throws ODataJPARuntimeException {
    JPALink link = new JPALink(oDataJPAContext);
    link.delete(uriParserResultView);
    link.save();
    return link.getTargetJPAEntity();
  }

  private List<Object> handlePaging(final List<Object> result, final GetEntitySetUriInfo uriParserResultView) {
    if (result == null) {
      return null;
    }
    JPAPageBuilder pageBuilder = new JPAPageBuilder();
    pageBuilder.pageSize(oDataJPAContext.getPageSize())
        .entities(result)
        .skipToken(uriParserResultView.getSkipToken());

    // $top/$skip with $inlinecount case handled in response builder to avoid multiple DB call
    if (uriParserResultView.getSkip() != null && uriParserResultView.getInlineCount() == null) {
      pageBuilder.skip(uriParserResultView.getSkip().intValue());
    }

    if (uriParserResultView.getTop() != null && uriParserResultView.getInlineCount() == null) {
      pageBuilder.top(uriParserResultView.getTop().intValue());
    }

    JPAPage page = pageBuilder.build();
    oDataJPAContext.setPaging(page);

    return page.getPagedEntities();
  }

  private List<Object> handlePaging(final Query query, final GetEntitySetUriInfo uriParserResultView) {

    JPAPageBuilder pageBuilder = new JPAPageBuilder();
    pageBuilder.pageSize(oDataJPAContext.getPageSize())
        .query(query)
        .skipToken(uriParserResultView.getSkipToken());

    // $top/$skip with $inlinecount case handled in response builder to avoid multiple DB call
    if (uriParserResultView.getSkip() != null && uriParserResultView.getInlineCount() == null) {
      pageBuilder.skip(uriParserResultView.getSkip().intValue());
    }

    if (uriParserResultView.getTop() != null && uriParserResultView.getInlineCount() == null) {
      pageBuilder.top(uriParserResultView.getTop().intValue());
    }

    JPAPage page = pageBuilder.build();
    oDataJPAContext.setPaging(page);

    return page.getPagedEntities();

  }

  private boolean setTransaction() {
    ODataJPATransaction transactionContext = oDataJPAContext.getODataJpaTransaction();
    if (!transactionContext.isActive()) {
      transactionContext.begin();
      return true;
    }

    return false;
  }
}
