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

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.olingo.commons.api.ODataException;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.constants.ODataServiceVersion;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.format.ODataFormat;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpMethod;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.server.api.OData;
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.ODataServerError;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.edm.provider.EdmProvider;
import org.apache.olingo.server.api.edm.provider.EntitySet;
import org.apache.olingo.server.api.edmx.EdmxReference;
import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionComplexProcessor;
import org.apache.olingo.server.api.processor.ActionEntityCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionEntityProcessor;
import org.apache.olingo.server.api.processor.ActionPrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.ActionPrimitiveProcessor;
import org.apache.olingo.server.api.processor.BatchProcessor;
import org.apache.olingo.server.api.processor.ComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.ComplexProcessor;
import org.apache.olingo.server.api.processor.CountComplexCollectionProcessor;
import org.apache.olingo.server.api.processor.CountEntityCollectionProcessor;
import org.apache.olingo.server.api.processor.CountPrimitiveCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityCollectionProcessor;
import org.apache.olingo.server.api.processor.EntityProcessor;
import org.apache.olingo.server.api.processor.ErrorProcessor;
import org.apache.olingo.server.api.processor.MediaEntityProcessor;
import org.apache.olingo.server.api.processor.MetadataProcessor;
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.processor.Processor;
import org.apache.olingo.server.api.processor.ReferenceCollectionProcessor;
import org.apache.olingo.server.api.processor.ReferenceProcessor;
import org.apache.olingo.server.api.processor.ServiceDocumentProcessor;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.tecsvc.provider.ContainerProvider;
import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
import org.junit.Test;

public class ODataHandlerTest {

  private static final String BASE_URI = "http://localhost/odata";

  @Test
  public void serviceDocumentNonDefault() throws Exception {
    final ServiceDocumentProcessor processor = mock(ServiceDocumentProcessor.class);
    final ODataResponse response = dispatch(HttpMethod.GET, "/", processor);
    assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());

    verify(processor).readServiceDocument(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.POST, "/", processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, "/", processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, "/", processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, "/", processor);
  }

  @Test
  public void serviceDocumentDefault() throws Exception {
    final ODataResponse response = dispatch(HttpMethod.GET, "/", null);
    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());

    String ct = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
    assertThat(ct, containsString("application/json"));
    assertThat(ct, containsString("odata.metadata=minimal"));

    assertNotNull(response.getContent());
    String doc = IOUtils.toString(response.getContent());

    assertThat(doc, containsString("\"@odata.context\" : \"" + BASE_URI + "/$metadata\""));
    assertThat(doc, containsString("\"value\" :"));
  }

  @Test
  public void serviceDocumentRedirect() throws Exception {
    final ODataResponse response = dispatch(HttpMethod.GET, "", null);
    assertEquals(HttpStatusCode.TEMPORARY_REDIRECT.getStatusCode(), response.getStatusCode());
    assertEquals(BASE_URI + "/", response.getHeaders().get(HttpHeader.LOCATION));
  }

  @Test
  public void metadataNonDefault() throws Exception {
    final MetadataProcessor processor = mock(MetadataProcessor.class);
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
    assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());

    verify(processor).readMetadata(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.POST, "$metadata", processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, "$metadata", processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, "$metadata", processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, "$metadata", processor);
  }

  @Test
  public void metadataDefault() throws Exception {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
    assertEquals(HttpContentType.APPLICATION_XML, response.getHeaders().get(HttpHeader.CONTENT_TYPE));

    assertNotNull(response.getContent());
    assertThat(IOUtils.toString(response.getContent()),
        containsString("<edmx:Edmx Version=\"4.0\""));
  }

  @Test
  public void maxVersionNone() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null);
    assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
  }

  @Test
  public void maxVersionSupported() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
        HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V40.toString(), null);
    assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
  }

  @Test
  public void maxVersionNotSupported() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", null,
        HttpHeader.ODATA_MAX_VERSION, ODataServiceVersion.V30.toString(), null);

    assertEquals(ODataServiceVersion.V40.toString(), response.getHeaders().get(HttpHeader.ODATA_VERSION));
    assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void contentNegotiationSupported() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=xml", null, null, null);
    assertEquals(HttpStatusCode.OK.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void contentNegotiationNotSupported() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=not/Supported", null, null, null);
    assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void contentNegotiationNotSupported2() {
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", "$format=notSupported", null, null, null);
    assertEquals(HttpStatusCode.NOT_ACCEPTABLE.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void unregisteredProcessor() {
    final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim", null);
    assertEquals(HttpStatusCode.NOT_IMPLEMENTED.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void uriParserExceptionResultsInRightResponseNotFound() throws Exception {
    final ODataResponse response = dispatch(HttpMethod.GET, "NotFound", null);
    assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void uriParserExceptionResultsInRightResponseBadRequest() throws Exception {
    final ODataResponse response = dispatch(HttpMethod.GET, "ESAllPrim('122')", null);
    assertEquals(HttpStatusCode.BAD_REQUEST.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void applicationExceptionInProcessor() throws Exception {
    MetadataProcessor processor = mock(MetadataProcessor.class);
    doThrow(new ODataApplicationException("msg", 425, Locale.ENGLISH)).when(processor).readMetadata(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));
    final ODataResponse response = dispatch(HttpMethod.GET, "$metadata", processor);
    assertEquals(425, response.getStatusCode());
  }

  @Test
  public void uriParserExceptionResultsInRightResponseEdmCause() throws Exception {
    final OData odata = OData.newInstance();
    final ServiceMetadata serviceMetadata = odata.createServiceMetadata(
        new EdmProvider() {
          public EntitySet getEntitySet(final FullQualifiedName entityContainer, final String entitySetName)
              throws ODataException {
            throw new ODataException("msg");
          }
        },
        Collections.<EdmxReference> emptyList());

    ODataRequest request = new ODataRequest();
    request.setMethod(HttpMethod.GET);
    request.setRawODataPath("EdmException");

    final ODataResponse response = new ODataHandler(odata, serviceMetadata).process(request);
    assertNotNull(response);
    assertEquals(HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatusCode());
  }

  @Test
  public void dispatchBatch() throws Exception {
    final String uri = "$batch";
    final BatchProcessor processor = mock(BatchProcessor.class);

    dispatch(HttpMethod.POST, uri, processor);
    // TODO: Verify that batch processing has been called.

    dispatchMethodNotAllowed(HttpMethod.GET, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void dispatchEntitySet() throws Exception {
    final String uri = "ESAllPrim";
    final EntityCollectionProcessor processor = mock(EntityCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readEntityCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void dispatchEntitySetCount() throws Exception {
    final String uri = "ESAllPrim/$count";
    final CountEntityCollectionProcessor processor = mock(CountEntityCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).countEntityCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void dispatchCountWithNavigation() throws Exception {
    final CountEntityCollectionProcessor processor = mock(CountEntityCollectionProcessor.class);
    dispatch(HttpMethod.GET, "ESAllPrim(0)/NavPropertyETTwoPrimMany/$count", processor);

    verify(processor).countEntityCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
  }

  @Test
  public void dispatchFunction() throws Exception {
    EntityProcessor entityProcessor = mock(EntityProcessor.class);
    dispatch(HttpMethod.GET, "FICRTETKeyNav()", entityProcessor);
    verify(entityProcessor).readEntity(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    EntityCollectionProcessor entityCollectionProcessor = mock(EntityCollectionProcessor.class);
    dispatch(HttpMethod.GET, "FICRTESTwoKeyNavParam(ParameterInt16=123)", entityCollectionProcessor);
    verify(entityCollectionProcessor).readEntityCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    PrimitiveProcessor primitiveProcessor = mock(PrimitiveProcessor.class);
    dispatch(HttpMethod.GET, "FICRTString()", primitiveProcessor);
    verify(primitiveProcessor).readPrimitive(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    PrimitiveCollectionProcessor primitiveCollectionProcessor = mock(PrimitiveCollectionProcessor.class);
    dispatch(HttpMethod.GET, "FICRTCollString()", primitiveCollectionProcessor);
    verify(primitiveCollectionProcessor).readPrimitiveCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    ComplexProcessor complexProcessor = mock(ComplexProcessor.class);
    dispatch(HttpMethod.GET, "FICRTCTTwoPrim()", complexProcessor);
    verify(complexProcessor).readComplex(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    ComplexCollectionProcessor complexCollectionProcessor = mock(ComplexCollectionProcessor.class);
    dispatch(HttpMethod.GET, "FICRTCollCTTwoPrim()", complexCollectionProcessor);
    verify(complexCollectionProcessor).readComplexCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.POST, "FICRTCollString()", mock(Processor.class));
    dispatchMethodNotAllowed(HttpMethod.PUT, "FICRTCollString()", mock(Processor.class));
    dispatchMethodNotAllowed(HttpMethod.DELETE, "FICRTCollString()", mock(Processor.class));
  }


  @Test
  public void dispatchAction() throws Exception {
    ActionPrimitiveProcessor primitiveProcessor = mock(ActionPrimitiveProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRT_STRING, primitiveProcessor);
    verify(primitiveProcessor).processActionPrimitive(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionPrimitiveCollectionProcessor primitiveCollectionProcessor = mock(ActionPrimitiveCollectionProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRT_COLL_STRING_TWO_PARAM, primitiveCollectionProcessor);
    verify(primitiveCollectionProcessor).processActionPrimitiveCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionComplexProcessor complexProcessor = mock(ActionComplexProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRTCT_TWO_PRIM_PARAM, complexProcessor);
    verify(complexProcessor).processActionComplex(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionComplexCollectionProcessor complexCollectionProcessor = mock(ActionComplexCollectionProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRT_COLL_CT_TWO_PRIM_PARAM, complexCollectionProcessor);
    verify(complexCollectionProcessor).processActionComplexCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionEntityProcessor entityProcessor = mock(ActionEntityProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRTET_TWO_KEY_TWO_PRIM_PARAM, entityProcessor);
    verify(entityProcessor).processActionEntity(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionEntityCollectionProcessor entityCollectionProcessor = mock(ActionEntityCollectionProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRT_COLL_ET_KEY_NAV_PARAM, entityCollectionProcessor);
    verify(entityCollectionProcessor).processActionEntityCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionEntityProcessor entityProcessorEs = mock(ActionEntityProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRTES_ALL_PRIM_PARAM, entityProcessorEs);
    verify(entityProcessorEs).processActionEntity(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    ActionEntityCollectionProcessor entityCollectionProcessorEs = mock(ActionEntityCollectionProcessor.class);
    dispatch(HttpMethod.POST, ContainerProvider.AIRT_COLL_ES_ALL_PRIM_PARAM, entityCollectionProcessorEs);
    verify(entityCollectionProcessorEs).processActionEntityCollection(
            any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
            any(ContentType.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.GET, "AIRTString", mock(Processor.class));
  }

  @Test
  public void dispatchEntity() throws Exception {
    final String uri = "ESAllPrim(0)";
    final EntityProcessor processor = mock(EntityProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readEntity(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updateEntity(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.PATCH, uri, processor);
    verify(processor, times(2)).updateEntity(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deleteEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatch(HttpMethod.POST, "ESAllPrim", processor);
    verify(processor).createEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class), any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchMedia() throws Exception {
    final String uri = "ESMedia(1)/$value";
    final MediaEntityProcessor processor = mock(MediaEntityProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readMediaEntity(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.POST, "ESMedia", processor);
    verify(processor).createMediaEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updateMediaEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class), any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deleteEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
  }

  @Test
  public void dispatchMediaDeleteIndirect() throws Exception {
    final MediaEntityProcessor processor = mock(MediaEntityProcessor.class);
    dispatch(HttpMethod.DELETE, "ESMedia(1)", processor);

    verify(processor).deleteEntity(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));
  }

  @Test
  public void dispatchPrimitiveProperty() throws Exception {
    final String uri = "ESAllPrim(0)/PropertyString";
    final PrimitiveProcessor processor = mock(PrimitiveProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readPrimitive(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updatePrimitive(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.PATCH, uri, processor);
    verify(processor, times(2)).updatePrimitive(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deletePrimitive(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchPrimitivePropertyValue() throws Exception {
    final String uri = "ESAllPrim(0)/PropertyString/$value";
    final PrimitiveValueProcessor processor = mock(PrimitiveValueProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readPrimitiveValue(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, null, HttpHeader.CONTENT_TYPE, ContentType.TEXT_PLAIN.toContentTypeString(),
        processor);
    verify(processor).updatePrimitive(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deletePrimitive(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
  }

  @Test
  public void dispatchPrimitiveCollectionProperty() throws Exception {
    final String uri = "ESMixPrimCollComp(7)/CollPropertyString";
    final PrimitiveCollectionProcessor processor = mock(PrimitiveCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readPrimitiveCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updatePrimitiveCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deletePrimitiveCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchPrimitiveCollectionPropertyCount() throws Exception {
    final String uri = "ESMixPrimCollComp(7)/CollPropertyString/$count";
    final CountPrimitiveCollectionProcessor processor = mock(CountPrimitiveCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).countPrimitiveCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void dispatchComplexProperty() throws Exception {
    final String uri = "ESMixPrimCollComp(7)/PropertyComp";
    final ComplexProcessor processor = mock(ComplexProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readComplex(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updateComplex(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.PATCH, uri, processor);
    verify(processor, times(2)).updateComplex(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deleteComplex(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchComplexCollectionProperty() throws Exception {
    final String uri = "ESMixPrimCollComp(7)/CollPropertyComp";
    final ComplexCollectionProcessor processor = mock(ComplexCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readComplexCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updateComplexCollection(
        any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class), any(ContentType.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deleteComplexCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchComplexCollectionPropertyCount() throws Exception {
    final String uri = "ESMixPrimCollComp(7)/CollPropertyComp/$count";
    final CountComplexCollectionProcessor processor = mock(CountComplexCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).countComplexCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void dispatchReference() throws Exception {
    final String uri = "ESAllPrim(0)/NavPropertyETTwoPrimOne/$ref";
    final ReferenceProcessor processor = mock(ReferenceProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatch(HttpMethod.PUT, uri, processor);
    verify(processor).updateReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatch(HttpMethod.PATCH, uri, processor);
    verify(processor, times(2)).updateReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatch(HttpMethod.DELETE, uri, processor);
    verify(processor).deleteReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class));

    dispatch(HttpMethod.POST, uri.replace("One", "Many"), processor);
    verify(processor).createReference(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.POST, uri, processor);
  }

  @Test
  public void dispatchReferenceCollection() throws Exception {
    final String uri = "ESAllPrim(0)/NavPropertyETTwoPrimMany/$ref";
    final ReferenceCollectionProcessor processor = mock(ReferenceCollectionProcessor.class);

    dispatch(HttpMethod.GET, uri, processor);
    verify(processor).readReferenceCollection(any(ODataRequest.class), any(ODataResponse.class), any(UriInfo.class),
        any(ContentType.class));

    dispatchMethodNotAllowed(HttpMethod.PUT, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.PATCH, uri, processor);
    dispatchMethodNotAllowed(HttpMethod.DELETE, uri, processor);
  }

  @Test
  public void unsupportedRequestContentType() throws Exception {
    EntityProcessor processor = mock(EntityProcessor.class);
    ErrorProcessor errorProcessor = mock(ErrorProcessor.class);
    dispatch(HttpMethod.POST, "ESAllPrim", "", HttpHeader.CONTENT_TYPE, "some/unsupported", errorProcessor);
    verifyZeroInteractions(processor);
    verify(errorProcessor).processError(any(ODataRequest.class), any(ODataResponse.class), any(ODataServerError.class),
            any(ContentType.class));
  }

  private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
      final String headerName, final String headerValue, final Processor processor) {
    Map<String, List<String>> headers = null;
    if(headerName != null) {
      headers = Collections.singletonMap(headerName, Collections.singletonList(headerValue));
    }
    List<Processor> processors = null;
    if(processor != null) {
      processors = Collections.singletonList(processor);
    }
    return dispatch(method, path, query, headers, processors);
  }


  private ODataResponse dispatch(final HttpMethod method, final String path, final String query,
      final Map<String, List<String>> headers, final List<Processor> processors) {
    ODataRequest request = new ODataRequest();
    request.setMethod(method);
    request.setRawBaseUri(BASE_URI);
    if (path.isEmpty()) {
      request.setRawRequestUri(BASE_URI);
    }
    request.setRawODataPath(path);
    request.setRawQueryPath(query);

    if (headers != null) {
      Set<Map.Entry<String, List<String>>> headerSet = headers.entrySet();
      for (Map.Entry<String, List<String>> headerItem : headerSet) {
        request.addHeader(headerItem.getKey(), headerItem.getValue());
      }
    }

    if(request.getHeaders(HttpHeader.CONTENT_TYPE) == null) {
      request.addHeader(HttpHeader.CONTENT_TYPE, Collections.singletonList(
              ODataFormat.JSON.getContentType(ODataServiceVersion.V40).toContentTypeString()));
    }

    final OData odata = OData.newInstance();
    final ServiceMetadata metadata = odata.createServiceMetadata(
        new EdmTechProvider(), Collections.<EdmxReference> emptyList());

    ODataHandler handler = new ODataHandler(odata, metadata);

    if (processors != null && !processors.isEmpty()) {
      for (Processor p : processors) {
        handler.register(p);
      }
    }

    final ODataResponse response = handler.process(request);
    assertNotNull(response);
    return response;
  }

  private ODataResponse dispatch(final HttpMethod method, final String path, final Processor processor) {
    return dispatch(method, path, null, null, null, processor);
  }

  private void dispatchMethodNotAllowed(final HttpMethod method, final String path, final Processor processor) {
    final ODataResponse response = dispatch(method, path, processor);
    assertEquals(HttpStatusCode.METHOD_NOT_ALLOWED.getStatusCode(), response.getStatusCode());
    assertNotNull(response.getContent());
  }
}
