/*
 * 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.server.tecsvc.processor;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import org.apache.olingo.commons.api.data.ContextURL;
import org.apache.olingo.commons.api.data.Entity;
import org.apache.olingo.commons.api.data.Property;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmPrimitiveType;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.edm.primitivetype.EdmPrimitiveTypeFactory;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.deserializer.DeserializerException;
import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionComplexProcessor;
import org.apache.olingo.server.api.processor.ActionPrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionPrimitiveProcessor;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.PrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.PrimitiveProcessor;
import org.apache.olingo.server.api.processor.PrimitiveValueProcessor;
import org.apache.olingo.server.api.serializer.ComplexSerializerOptions;
import org.apache.olingo.server.api.serializer.FixedFormatSerializer;
import org.apache.olingo.server.api.serializer.ODataSerializer;
import org.apache.olingo.server.api.serializer.PrimitiveSerializerOptions;
import org.apache.olingo.server.api.serializer.PrimitiveValueSerializerOptions;
import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.serializer.SerializerException;
import org.apache.olingo.server.api.uri.UriHelper;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoResource;
import org.apache.olingo.server.api.uri.UriResource;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceKind;
import org.apache.olingo.server.api.uri.UriResourceProperty;
import org.apache.olingo.server.api.uri.queryoption.ExpandOption;
import org.apache.olingo.server.api.uri.queryoption.SelectOption;
import org.apache.olingo.server.tecsvc.data.DataProvider;

/**
 * Technical Processor which provides functionality related to primitive and complex types and collections thereof.
 */
public class TechnicalPrimitiveComplexProcessor extends TechnicalProcessor
    implements PrimitiveProcessor, PrimitiveValueProcessor, ActionPrimitiveProcessor,
        PrimitiveCollectionProcessor, ActionPrimitiveCollectionProcessor,
        ComplexProcessor, ActionComplexProcessor,
        ComplexCollectionProcessor, ActionComplexCollectionProcessor {

  public TechnicalPrimitiveComplexProcessor(final DataProvider dataProvider) {
    super(dataProvider);
  }

  @Override
  public void readPrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, SerializerException {
    readProperty(response, uriInfo, contentType, RepresentationType.PRIMITIVE);
  }

  @Override
  public void updatePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void deletePrimitive(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException {
    deleteProperty(response, uriInfo);
  }

  @Override
  public void processActionPrimitive(final ODataRequest request, final ODataResponse response,
                                      final UriInfo uriInfo,
                                      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void readPrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, SerializerException {
    readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_PRIMITIVE);
  }

  @Override
  public void updatePrimitiveCollection(final ODataRequest request, final ODataResponse response,
      final UriInfo uriInfo, final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void deletePrimitiveCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException {
    deleteProperty(response, uriInfo);
  }

  @Override
  public void processActionPrimitiveCollection(final ODataRequest request, final ODataResponse response,
                                               final UriInfo uriInfo,
                                               final ContentType requestFormat, final ContentType responseFormat)
          throws ODataApplicationException, DeserializerException,
      SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void readComplex(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, SerializerException {
    readProperty(response, uriInfo, contentType, RepresentationType.COMPLEX);
  }

  @Override
  public void updateComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void processActionComplex(ODataRequest request, ODataResponse response, UriInfo uriInfo, ContentType
      requestFormat, ContentType responseFormat) throws ODataApplicationException, DeserializerException,
      SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void deleteComplex(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException {
    deleteProperty(response, uriInfo);
  }

  @Override
  public void readComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, SerializerException {
    readProperty(response, uriInfo, contentType, RepresentationType.COLLECTION_COMPLEX);
  }

  @Override
  public void updateComplexCollection(final ODataRequest request, final ODataResponse response, final UriInfo uriInfo,
      final ContentType requestFormat, final ContentType responseFormat)
      throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void processActionComplexCollection(ODataRequest request, ODataResponse response,
                                             UriInfo uriInfo, ContentType requestFormat,
                                             ContentType responseFormat)
          throws ODataApplicationException, DeserializerException, SerializerException {
    throw new ODataApplicationException("Not supported yet.",
        HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
  }

  @Override
  public void deleteComplexCollection(final ODataRequest request, ODataResponse response, final UriInfo uriInfo)
      throws ODataApplicationException {
    deleteProperty(response, uriInfo);
  }

  private void readProperty(final ODataResponse response, final UriInfo uriInfo, final ContentType contentType,
      final RepresentationType representationType) throws ODataApplicationException, SerializerException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validateOptions(resource);
    validatePath(resource);

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
    final List<String> path = getPropertyPath(resourceParts);

    final Property property = getPropertyData(resourceEntitySet, path);

    if (property == null) {
      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
    } else {
      if (property.getValue() == null) {
        response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
      } else {
        final EdmEntitySet edmEntitySet = getEdmEntitySet(resource);
        final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();

        final ODataFormat format = ODataFormat.fromContentType(contentType);
        ODataSerializer serializer = odata.createSerializer(format);
        final ExpandOption expand = uriInfo.getExpandOption();
        final SelectOption select = uriInfo.getSelectOption();
        final UriHelper helper = odata.createUriHelper();
        final ContextURL contextURL = format == ODataFormat.JSON_NO_METADATA ? null :
            ContextURL.with().entitySet(edmEntitySet)
                .keyPath(helper.buildContextURLKeyPredicate(
                    ((UriResourceEntitySet) resourceParts.get(0)).getKeyPredicates()))
                .navOrPropertyPath(buildPropertyPath(path))
                .selectList(edmProperty.isPrimitive() ? null :
                    helper.buildContextURLSelectList((EdmStructuredType) edmProperty.getType(), expand, select))
                .build();
        switch (representationType) {
        case PRIMITIVE:
          response.setContent(serializer.primitive((EdmPrimitiveType) edmProperty.getType(), property,
              PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
          break;
        case COMPLEX:
          response.setContent(serializer.complex((EdmComplexType) edmProperty.getType(), property,
              ComplexSerializerOptions.with().contextURL(contextURL)
                  .expand(expand).select(select)
                  .build()));
          break;
        case COLLECTION_PRIMITIVE:
          response.setContent(serializer.primitiveCollection((EdmPrimitiveType) edmProperty.getType(), property,
              PrimitiveSerializerOptions.with().contextURL(contextURL).facetsFrom(edmProperty).build()));
          break;
        case COLLECTION_COMPLEX:
          response.setContent(serializer.complexCollection((EdmComplexType) edmProperty.getType(), property,
              ComplexSerializerOptions.with().contextURL(contextURL)
                  .expand(expand).select(select)
                  .build()));
          break;
        default:
          break;
        }
        response.setStatusCode(HttpStatusCode.OK.getStatusCode());
        response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
      }
    }
  }

  private void deleteProperty(final ODataResponse response, final UriInfo uriInfo) throws ODataApplicationException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validatePath(resource);

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
    final List<String> path = getPropertyPath(resourceParts);

    final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
    final Property property = getPropertyData(resourceEntitySet, path);

    if (edmProperty.isNullable() == null || edmProperty.isNullable()) {
      property.setValue(property.getValueType(), edmProperty.isCollection() ? Collections.emptyList() : null);
      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
    } else {
      throw new ODataApplicationException("Not nullable.", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT);
    }
  }

  private Property getPropertyData(final UriResourceEntitySet resourceEntitySet, final List<String> path)
      throws ODataApplicationException {
    final Entity entity = dataProvider.read(resourceEntitySet.getEntitySet(), resourceEntitySet.getKeyPredicates());
    if (entity == null) {
      throw new ODataApplicationException("Nothing found.", HttpStatusCode.NOT_FOUND.getStatusCode(), Locale.ROOT);
    } else {
      Property property = entity.getProperty(path.get(0));
      for (final String name : path.subList(1, path.size())) {
        if (property != null && (property.isLinkedComplex() || property.isComplex())) {
          final List<Property> complex = property.isLinkedComplex() ?
              property.asLinkedComplex().getValue() : property.asComplex();
          property = null;
          for (final Property innerProperty : complex) {
            if (innerProperty.getName().equals(name)) {
              property = innerProperty;
              break;
            }
          }
        }
      }
      return property;
    }
  }

  private List<String> getPropertyPath(final List<UriResource> path) {
    List<String> result = new LinkedList<String>();
    int index = 1;
    while (index < path.size() && path.get(index) instanceof UriResourceProperty) {
      result.add(((UriResourceProperty) path.get(index)).getProperty().getName());
      index++;
    }
    return result;
  }

  private String buildPropertyPath(final List<String> path) {
    StringBuilder result = new StringBuilder();
    for (final String segment : path) {
      result.append(result.length() == 0 ? "" : '/').append(segment);
    }
    return result.toString();
  }

  @Override
  public void readPrimitiveValue(final ODataRequest request, ODataResponse response, final UriInfo uriInfo,
      final ContentType contentType) throws ODataApplicationException, SerializerException {
    final UriInfoResource resource = uriInfo.asUriInfoResource();
    validateOptions(resource);
    validatePath(resource);

    final List<UriResource> resourceParts = resource.getUriResourceParts();
    final UriResourceEntitySet resourceEntitySet = (UriResourceEntitySet) resourceParts.get(0);
    final List<String> path = getPropertyPath(resourceParts);

    final Property property = getPropertyData(resourceEntitySet, path);

    if (property == null || property.getValue() == null) {
      response.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
    } else {
      final EdmProperty edmProperty = ((UriResourceProperty) resourceParts.get(path.size())).getProperty();
      final EdmPrimitiveType type = (EdmPrimitiveType) edmProperty.getType();
      final FixedFormatSerializer serializer = odata.createFixedFormatSerializer();
      response.setContent(type == EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary) ?
          serializer.binary((byte[]) property.getValue()) :
          serializer.primitiveValue(type, property.getValue(),
              PrimitiveValueSerializerOptions.with().facetsFrom(edmProperty).build()));
      response.setHeader(HttpHeader.CONTENT_TYPE, contentType.toContentTypeString());
      response.setStatusCode(HttpStatusCode.OK.getStatusCode());
    }
  }

  private void validatePath(final UriInfoResource uriInfo) throws ODataApplicationException {
    final List<UriResource> resourcePaths = uriInfo.getUriResourceParts();
    for (final UriResource segment : resourcePaths.subList(1, resourcePaths.size())) {
      final UriResourceKind kind = segment.getKind();
      if (kind != UriResourceKind.primitiveProperty
          && kind != UriResourceKind.complexProperty
          && kind != UriResourceKind.count
          && kind != UriResourceKind.value) {
        throw new ODataApplicationException("Invalid resource type.",
            HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), Locale.ROOT);
      }
    }
  }
}
