/*
 * 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 java.net.URI;
import java.net.URISyntaxException;
import java.util.StringTokenizer;

import org.apache.olingo.commons.api.ex.ODataException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
import org.apache.olingo.commons.core.Decoder;
import org.apache.olingo.server.api.OData;
import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.ODataLibraryException;
import org.apache.olingo.server.api.ODataRequest;
import org.apache.olingo.server.api.ODataResponse;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.CustomContentTypeSupport;
import org.apache.olingo.server.api.serializer.RepresentationType;
import org.apache.olingo.server.api.uri.UriInfo;
import org.apache.olingo.server.api.uri.UriInfoBatch;
import org.apache.olingo.server.api.uri.UriInfoCrossjoin;
import org.apache.olingo.server.api.uri.UriInfoEntityId;
import org.apache.olingo.server.api.uri.UriInfoMetadata;
import org.apache.olingo.server.api.uri.UriInfoService;
import org.apache.olingo.server.api.uri.UriResourceAction;
import org.apache.olingo.server.api.uri.UriResourceComplexProperty;
import org.apache.olingo.server.api.uri.UriResourceCount;
import org.apache.olingo.server.api.uri.UriResourceEntitySet;
import org.apache.olingo.server.api.uri.UriResourceFunction;
import org.apache.olingo.server.api.uri.UriResourceNavigation;
import org.apache.olingo.server.api.uri.UriResourcePrimitiveProperty;
import org.apache.olingo.server.api.uri.UriResourceRef;
import org.apache.olingo.server.api.uri.UriResourceSingleton;
import org.apache.olingo.server.api.uri.UriResourceValue;
import org.apache.olingo.server.api.uri.queryoption.ApplyOption;
import org.apache.olingo.server.api.uri.queryoption.FormatOption;
import org.apache.olingo.server.core.requests.ActionRequest;
import org.apache.olingo.server.core.requests.BatchRequest;
import org.apache.olingo.server.core.requests.DataRequest;
import org.apache.olingo.server.core.requests.FunctionRequest;
import org.apache.olingo.server.core.requests.MediaRequest;
import org.apache.olingo.server.core.requests.MetadataRequest;
import org.apache.olingo.server.core.requests.OperationRequest;
import org.apache.olingo.server.core.requests.ServiceDocumentRequest;
import org.apache.olingo.server.core.uri.parser.Parser;
import org.apache.olingo.server.core.uri.validator.UriValidator;

public class ServiceDispatcher extends RequestURLHierarchyVisitor {
  private final OData odata;
  protected ServiceMetadata metadata;
  protected ServiceHandler handler;
  protected CustomContentTypeSupport customContentSupport;
  private String idOption;
  protected ServiceRequest request;

  public ServiceDispatcher(OData odata, ServiceMetadata metadata, ServiceHandler handler,
      CustomContentTypeSupport customContentSupport) {
    this.odata = odata;
    this.metadata = metadata;
    this.handler = handler;
    this.customContentSupport = customContentSupport;
  }

  public void execute(ODataRequest odRequest, ODataResponse odResponse) {
    FormatOption formatOption = null;
    ODataException oDataException = null;
    try {
      String path = odRequest.getRawODataPath();      
      String query = odRequest.getRawQueryPath();      
      if(path.indexOf("$entity") != -1) {
        executeIdOption(query, odRequest, odResponse);
      } else {
        UriInfo uriInfo = new Parser(this.metadata.getEdm(), odata)
          .parseUri(path, query, null, odRequest.getRawBaseUri());
        
        formatOption = uriInfo.getFormatOption();
        
        internalExecute(uriInfo, odRequest, odResponse);
      }
      return;
    } catch(ODataLibraryException | ODataApplicationException e) {
    	oDataException = e;
    }
    ContentType contentType = ContentType.JSON;
    try {
      contentType = ContentNegotiator.doContentNegotiation(formatOption, 
          odRequest, this.customContentSupport, RepresentationType.ERROR);
    } catch (ContentNegotiatorException e) {
      // ignore, default to JSON
    }
    handleException(oDataException, contentType, odRequest, odResponse);
  }
  
  protected void handleException(ODataException e, ContentType contentType,
      ODataRequest odRequest, ODataResponse odResponse) {
    ErrorHandler errorHandler = new ErrorHandler(this.odata, this.metadata,
        this.handler, contentType);
    errorHandler.handleException(e, odRequest, odResponse);    
  }
  
  private void internalExecute(UriInfo uriInfo, ODataRequest odRequest,
      ODataResponse odResponse) throws ODataLibraryException,
      ODataApplicationException {

    new UriValidator().validate(uriInfo, odRequest.getMethod());

    // part1, 8.2.6
    String isolation = odRequest.getHeader(HttpHeader.ODATA_ISOLATION);
    if (isolation != null && "snapshot".equals(isolation) && !this.handler.supportsDataIsolation()) {
      odResponse.setStatusCode(HttpStatusCode.PRECONDITION_FAILED.getStatusCode());
      return;
    }
    
    visit(uriInfo);

    // this should cover for any unsupported calls until they are implemented
    if (this.request == null) {
      this.request = new ServiceRequest(this.odata, this.metadata) {
        @Override
        public ContentType getResponseContentType() throws ContentNegotiatorException {
          return ContentType.APPLICATION_JSON;
        }

        @Override
        public void execute(ServiceHandler handler, ODataResponse response)
            throws ODataLibraryException, ODataApplicationException {
          handler.anyUnsupported(getODataRequest(), response);
        }
      };
    }

    // To handle $entity?$id=http://localhost/EntitySet(key) as
    // http://localhost/EntitySet(key)
    if (this.idOption != null) {
      try {
        this.request.setODataRequest(odRequest);
        this.request = this.request.parseLink(new URI(this.idOption));
      } catch (URISyntaxException e) {
        throw new ODataHandlerException("Invalid $id value",
            ODataHandlerException.MessageKeys.FUNCTIONALITY_NOT_IMPLEMENTED, this.idOption);
      }
    }

    this.request.setODataRequest(odRequest);
    this.request.setUriInfo(uriInfo);
    this.request.setCustomContentTypeSupport(this.customContentSupport);
    this.request.execute(this.handler, odResponse);
  }

  @Override
  public void visit(UriInfoMetadata info) {
    this.request = new MetadataRequest(this.odata, this.metadata);
  }

  @Override
  public void visit(UriInfoService info) {
    this.request = new ServiceDocumentRequest(this.odata, this.metadata);
  }

  @Override
  public void visit(UriResourceEntitySet info) {
    DataRequest dataRequest = new DataRequest(this.odata, this.metadata);
    dataRequest.setUriResourceEntitySet(info);
    this.request = dataRequest;
  }

  @Override
  public void visit(UriResourceCount option) {
    if (this.request instanceof DataRequest) {
      DataRequest dataRequest = (DataRequest) this.request;
      dataRequest.setCountRequest(option != null);
    } else if (this.request instanceof OperationRequest) {
      OperationRequest opRequest = (OperationRequest) this.request;
      opRequest.setCountRequest(option != null);      
    }
  }

  @Override
  public void visit(UriResourceComplexProperty info) {
    DataRequest dataRequest = (DataRequest) this.request;
    dataRequest.setUriResourceProperty(info);
  }

  @Override
  public void visit(UriResourcePrimitiveProperty info) {
    DataRequest dataRequest = (DataRequest) this.request;
    dataRequest.setUriResourceProperty(info);
  }

  @Override
  public void visit(UriResourceValue info) {
    DataRequest dataRequest = (DataRequest) this.request;
    if (dataRequest.isPropertyRequest()) {
      dataRequest.setValueRequest(info != null);
    } else {
      MediaRequest mediaRequest = new MediaRequest(this.odata, this.metadata);
      mediaRequest.setUriResourceEntitySet(dataRequest.getUriResourceEntitySet());
      this.request = mediaRequest;
    }
  }

  @Override
  public void visit(UriResourceAction info) {
    ActionRequest actionRequest = new ActionRequest(this.odata, this.metadata);
    actionRequest.setUriResourceAction(info);
    this.request = actionRequest;
  }

  @Override
  public void visit(UriResourceFunction info) {
    FunctionRequest functionRequest = new FunctionRequest(this.odata, this.metadata);
    functionRequest.setUriResourceFunction(info);
    this.request = functionRequest;
  }

  @Override
  public void visit(UriResourceNavigation info) {
    DataRequest dataRequest = (DataRequest) this.request;
    dataRequest.addUriResourceNavigation(info);
  }

  @Override
  public void visit(UriResourceRef info) {
    // this is same as data, but return is just entity references.
    DataRequest dataRequest = (DataRequest) this.request;
    dataRequest.setReferenceRequest(info != null);
  }

  @Override
  public void visit(UriInfoBatch info) {
    this.request = new BatchRequest(this.odata, this.metadata);
  }

  @Override
  public void visit(UriResourceSingleton info) {
    DataRequest dataRequest = new DataRequest(this.odata, this.metadata);
    dataRequest.setUriResourceSingleton(info);
    this.request = dataRequest;
  }

  @Override
  public void visit(UriInfoEntityId info) {
    DataRequest dataRequest = new DataRequest(this.odata, this.metadata);
    this.request = dataRequest;
    super.visit(info);
  }

  @Override
  public void visit(UriInfoCrossjoin info) {
    DataRequest dataRequest = new DataRequest(this.odata, this.metadata);
    dataRequest.setCrossJoin(info);
    this.request = dataRequest;
  }
  
  @Override
  public void visit(ApplyOption option) {
    ((DataRequest)this.request).setApply(option);
  }
  
  private void executeIdOption(String query, ODataRequest odRequest,
      ODataResponse odResponse) throws ODataLibraryException,
      ODataApplicationException {
    StringBuilder sb = new StringBuilder();
    StringTokenizer st = new StringTokenizer(query, "&");
    boolean first = true;
    while(st.hasMoreTokens()) {
      String token = st.nextToken();
      if (token.startsWith("$id=")) {
        URI id = URI.create(Decoder.decode(token.substring(4)));
        sb.append(id.getPath());
      } else {
        if (first) {
          sb.append("?");
        } else {
          sb.append("&");
        }
        sb.append(token);
      }
    }    
    DataRequest dataRequest = new DataRequest(this.odata, this.metadata);
    this.request = dataRequest;
    
    this.request.setODataRequest(odRequest);
    this.request = this.request.parseLink(URI.create(sb.toString()));

    this.request.setODataRequest(odRequest);
    this.request.setCustomContentTypeSupport(this.customContentSupport);
    this.request.execute(this.handler, odResponse);    
  }
}
