/*
 * 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.serializer.json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.olingo.commons.api.edm.EdmAction;
import org.apache.olingo.commons.api.edm.EdmActionImport;
import org.apache.olingo.commons.api.edm.EdmAnnotatable;
import org.apache.olingo.commons.api.edm.EdmAnnotation;
import org.apache.olingo.commons.api.edm.EdmAnnotations;
import org.apache.olingo.commons.api.edm.EdmBindingTarget;
import org.apache.olingo.commons.api.edm.EdmComplexType;
import org.apache.olingo.commons.api.edm.EdmEntityContainer;
import org.apache.olingo.commons.api.edm.EdmEntitySet;
import org.apache.olingo.commons.api.edm.EdmEntityType;
import org.apache.olingo.commons.api.edm.EdmEnumType;
import org.apache.olingo.commons.api.edm.EdmFunction;
import org.apache.olingo.commons.api.edm.EdmFunctionImport;
import org.apache.olingo.commons.api.edm.EdmKeyPropertyRef;
import org.apache.olingo.commons.api.edm.EdmMember;
import org.apache.olingo.commons.api.edm.EdmNavigationProperty;
import org.apache.olingo.commons.api.edm.EdmNavigationPropertyBinding;
import org.apache.olingo.commons.api.edm.EdmOperation;
import org.apache.olingo.commons.api.edm.EdmParameter;
import org.apache.olingo.commons.api.edm.EdmProperty;
import org.apache.olingo.commons.api.edm.EdmReferentialConstraint;
import org.apache.olingo.commons.api.edm.EdmReturnType;
import org.apache.olingo.commons.api.edm.EdmSchema;
import org.apache.olingo.commons.api.edm.EdmSingleton;
import org.apache.olingo.commons.api.edm.EdmStructuredType;
import org.apache.olingo.commons.api.edm.EdmTerm;
import org.apache.olingo.commons.api.edm.EdmType;
import org.apache.olingo.commons.api.edm.EdmTypeDefinition;
import org.apache.olingo.commons.api.edm.FullQualifiedName;
import org.apache.olingo.commons.api.edm.TargetType;
import org.apache.olingo.commons.api.edm.annotation.EdmApply;
import org.apache.olingo.commons.api.edm.annotation.EdmCast;
import org.apache.olingo.commons.api.edm.annotation.EdmConstantExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmDynamicExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmIf;
import org.apache.olingo.commons.api.edm.annotation.EdmIsOf;
import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElement;
import org.apache.olingo.commons.api.edm.annotation.EdmLabeledElementReference;
import org.apache.olingo.commons.api.edm.annotation.EdmLogicalOrComparisonExpression;
import org.apache.olingo.commons.api.edm.annotation.EdmNavigationPropertyPath;
import org.apache.olingo.commons.api.edm.annotation.EdmNot;
import org.apache.olingo.commons.api.edm.annotation.EdmNull;
import org.apache.olingo.commons.api.edm.annotation.EdmPath;
import org.apache.olingo.commons.api.edm.annotation.EdmPropertyPath;
import org.apache.olingo.commons.api.edm.annotation.EdmPropertyValue;
import org.apache.olingo.commons.api.edm.annotation.EdmRecord;
import org.apache.olingo.commons.api.edm.annotation.EdmUrlRef;
import org.apache.olingo.commons.api.edm.constants.EdmTypeKind;
import org.apache.olingo.commons.api.edmx.EdmxReference;
import org.apache.olingo.commons.api.edmx.EdmxReferenceInclude;
import org.apache.olingo.commons.api.edmx.EdmxReferenceIncludeAnnotation;
import org.apache.olingo.server.api.ServiceMetadata;
import org.apache.olingo.server.api.serializer.Kind;
import org.apache.olingo.server.api.serializer.SerializerException;

import com.fasterxml.jackson.core.JsonGenerator;

public class MetadataDocumentJsonSerializer {
  
  private final ServiceMetadata serviceMetadata;
  private final Map<String, String> namespaceToAlias = new HashMap<>();
  private static final String DOLLAR = "$";
  private static final String VERSION = DOLLAR + "Version";
  private static final String REFERENCES = DOLLAR + "Reference";
  private static final String INCLUDE = DOLLAR + "Include";
  private static final String NAMESPACE = DOLLAR + "Namespace";
  private static final String ALIAS = DOLLAR + "Alias";
  private static final String INCLUDE_ANNOTATIONS = DOLLAR + "IncludeAnnotations";
  private static final String TERM_NAMESPACE = DOLLAR + "TermNamespace";
  private static final String TARGET_NAMESPACE = DOLLAR + "TargetNamespace";
  private static final String QUALIFIER = DOLLAR + "Qualifier";
  private static final String IS_FLAGS = DOLLAR + "IsFlags";
  private static final String UNDERLYING_TYPE = DOLLAR + "UnderlyingType";
  private static final String KIND = DOLLAR + "Kind";
  private static final String MAX_LENGTH = DOLLAR + "MaxLength";
  private static final String PRECISION = DOLLAR + "Precision";
  private static final String SCALE = DOLLAR + "Scale";
  private static final String SRID = DOLLAR + "SRID";
  private static final String COLLECTION = DOLLAR + "Collection";
  private static final String BASE_TYPE = DOLLAR + "BaseType";
  private static final String HAS_STREAM = DOLLAR + "HasStream";
  private static final String KEY = DOLLAR + "Key";
  private static final String ABSTRACT = DOLLAR + "Abstract";
  private static final String TYPE = DOLLAR + "Type";
  private static final String NULLABLE = DOLLAR + "Nullable";
  private static final String UNICODE = DOLLAR + "Unicode";
  private static final String DEFAULT_VALUE = DOLLAR + "DefaultValue";
  private static final String PARTNER = DOLLAR + "Partner";
  private static final String CONTAINS_TARGET = DOLLAR + "ContainsTarget";
  private static final String REFERENTIAL_CONSTRAINT = DOLLAR + "ReferentialConstraint";
  private static final String ISBOUND = DOLLAR + "IsBound";
  private static final String ENTITY_SET_PATH = DOLLAR + "EntitySetPath";
  private static final String PARAMETER = DOLLAR + "Parameter";
  private static final String RETURN_TYPE = DOLLAR + "ReturnType";
  private static final String ISCOMPOSABLE = DOLLAR + "IsComposable";
  private static final String PARAMETER_NAME = DOLLAR + "Name";
  private static final String BASE_TERM = DOLLAR + "BaseTerm";
  private static final String APPLIES_TO = DOLLAR + "AppliesTo";
  private static final String NAVIGATION_PROPERTY_BINDING = DOLLAR + "NavigationPropertyBinding";
  private static final String EXTENDS = DOLLAR + "Extends";
  private static final String INCLUDE_IN_SERV_DOC = DOLLAR + "IncludeInServiceDocument";
  private static final String ANNOTATION = DOLLAR + "Annotations";
  private static final String ANNOTATION_PATH = DOLLAR + "Path";
  private static final String NAME = DOLLAR + "Name";

  public MetadataDocumentJsonSerializer(final ServiceMetadata serviceMetadata) throws SerializerException {
    if (serviceMetadata == null || serviceMetadata.getEdm() == null) {
      throw new SerializerException("Service Metadata and EDM must not be null for a service.",
          SerializerException.MessageKeys.NULL_METADATA_OR_EDM);
    }
    this.serviceMetadata = serviceMetadata;
  }
  
  public void writeMetadataDocument(final JsonGenerator json) throws SerializerException, IOException {
    json.writeStartObject();
    json.writeStringField(VERSION, "4.01");
    if (!serviceMetadata.getReferences().isEmpty()) {
      appendReference(json);
    }
    appendDataServices(json);
    json.writeEndObject();
  }

  private void appendDataServices(JsonGenerator json) throws SerializerException, IOException {
    for (EdmSchema schema : serviceMetadata.getEdm().getSchemas()) {
      appendSchema(json, schema);
    }
  }

  private void appendSchema(JsonGenerator json, EdmSchema schema) 
      throws SerializerException, IOException {
    json.writeFieldName(schema.getNamespace());
    json.writeStartObject();
    if (schema.getAlias() != null) {
      json.writeStringField(ALIAS, schema.getAlias());
      namespaceToAlias.put(schema.getNamespace(), schema.getAlias());
    }
    // EnumTypes
    appendEnumTypes(json, schema.getEnumTypes());
    
    // TypeDefinitions
    appendTypeDefinitions(json, schema.getTypeDefinitions());
    
    // EntityTypes
    appendEntityTypes(json, schema.getEntityTypes());
    
    // ComplexTypes
    appendComplexTypes(json, schema.getComplexTypes());
    
    // Actions
    appendActions(json, schema.getActions());
    
    // Functions
    appendFunctions(json, schema.getFunctions());
    
    //Terms
    appendTerms(json, schema.getTerms());
    
    // EntityContainer
    appendEntityContainer(json, schema.getEntityContainer());
 
    // AnnotationGroups
    appendAnnotationGroups(json, schema.getAnnotationGroups());

    appendAnnotations(json, schema, null);
    
    json.writeEndObject();
  }

  private void appendAnnotationGroups(final JsonGenerator json, 
      final List<EdmAnnotations> annotationGroups) throws SerializerException, IOException {
    if (!annotationGroups.isEmpty()) {
      json.writeObjectFieldStart(ANNOTATION);
    }
    for (EdmAnnotations annotationGroup : annotationGroups) {
      appendAnnotationGroup(json, annotationGroup);
    }
    if (!annotationGroups.isEmpty()) {
      json.writeEndObject();
    }
  }

  private void appendAnnotationGroup(final JsonGenerator json, 
      final EdmAnnotations annotationGroup) throws SerializerException, IOException {
    String targetPath = annotationGroup.getTargetPath();
    if (annotationGroup.getQualifier() != null) {
      json.writeObjectFieldStart(targetPath + "#" + annotationGroup.getQualifier());
    } else {
      json.writeObjectFieldStart(targetPath);
    }
    appendAnnotations(json, annotationGroup, null);
    json.writeEndObject();
  }

  private void appendEntityContainer(final JsonGenerator json, 
      final EdmEntityContainer container) throws SerializerException, IOException {
    if (container != null) {
      json.writeObjectFieldStart(container.getName());
      json.writeStringField(KIND, Kind.EntityContainer.name());
      FullQualifiedName parentContainerName = container.getParentContainerName();
      if (parentContainerName != null) {
        String parentContainerNameString;
        if (namespaceToAlias.get(parentContainerName.getNamespace()) != null) {
          parentContainerNameString =
              namespaceToAlias.get(parentContainerName.getNamespace()) + "." + parentContainerName.getName();
        } else {
          parentContainerNameString = parentContainerName.getFullQualifiedNameAsString();
        }
        json.writeObjectFieldStart(Kind.Extending.name());
        json.writeStringField(KIND, Kind.EntityContainer.name());
        json.writeStringField(EXTENDS, parentContainerNameString);
        json.writeEndObject();
      }

      // EntitySets
      appendEntitySets(json, container.getEntitySets());

      String containerNamespace;
      if (namespaceToAlias.get(container.getNamespace()) != null) {
        containerNamespace = namespaceToAlias.get(container.getNamespace());
      } else {
        containerNamespace = container.getNamespace();
      }
      // ActionImports
      appendActionImports(json, container.getActionImports(), containerNamespace);
     
      // FunctionImports
      appendFunctionImports(json, container.getFunctionImports(), containerNamespace);

       
      // Singletons
      appendSingletons(json, container.getSingletons());

      // Annotations
      appendAnnotations(json, container, null);

      json.writeEndObject();
    }
    
  }

  private void appendSingletons(final JsonGenerator json, 
      final List<EdmSingleton> singletons) throws SerializerException, IOException {
    for (EdmSingleton singleton : singletons) {
      json.writeObjectFieldStart(singleton.getName());
      json.writeStringField(KIND, Kind.Singleton.name());
      json.writeStringField(TYPE, getAliasedFullQualifiedName(singleton.getEntityType()));
      
      appendNavigationPropertyBindings(json, singleton);
      appendAnnotations(json, singleton, null);
      json.writeEndObject();
    }
  }

  private void appendFunctionImports(final JsonGenerator json, final List<EdmFunctionImport> functionImports,
      final String containerNamespace) throws SerializerException, IOException {
    for (EdmFunctionImport functionImport : functionImports) {
      json.writeObjectFieldStart(functionImport.getName());

      json.writeStringField(KIND, Kind.FunctionImport.name());
      String functionFQNString;
      FullQualifiedName functionFqn = functionImport.getFunctionFqn();
      if (namespaceToAlias.get(functionFqn.getNamespace()) != null) {
        functionFQNString = namespaceToAlias.get(functionFqn.getNamespace()) + "." + functionFqn.getName();
      } else {
        functionFQNString = functionFqn.getFullQualifiedNameAsString();
      }
      json.writeStringField(DOLLAR + Kind.Function.name(), functionFQNString);

      EdmEntitySet returnedEntitySet = functionImport.getReturnedEntitySet();
      if (returnedEntitySet != null) {
        json.writeStringField(DOLLAR + Kind.EntitySet.name(), 
            containerNamespace + "." + returnedEntitySet.getName());
      }
      // Default is false and we do not write the default
      if (functionImport.isIncludeInServiceDocument()) {
        json.writeBooleanField(INCLUDE_IN_SERV_DOC, functionImport.isIncludeInServiceDocument());
      }
      appendAnnotations(json, functionImport, null);
      json.writeEndObject();
    }
  }

  private void appendActionImports(final JsonGenerator json, 
      final List<EdmActionImport> actionImports, String containerNamespace) 
          throws SerializerException, IOException {
    for (EdmActionImport actionImport : actionImports) {
      json.writeObjectFieldStart(actionImport.getName());
      json.writeStringField(KIND, Kind.ActionImport.name());
      json.writeStringField(DOLLAR + Kind.Action.name(), getAliasedFullQualifiedName(actionImport.getUnboundAction()));
      if (actionImport.getReturnedEntitySet() != null) {
        json.writeStringField(DOLLAR + Kind.EntitySet.name(), 
            containerNamespace + "." + actionImport.getReturnedEntitySet().getName());
      }
      appendAnnotations(json, actionImport, null);
      json.writeEndObject();
    }
    
  }

  private void appendEntitySets(final JsonGenerator json, 
      final List<EdmEntitySet> entitySets) throws SerializerException, IOException {
    for (EdmEntitySet entitySet : entitySets) {
      json.writeObjectFieldStart(entitySet.getName());
      json.writeStringField(KIND, Kind.EntitySet.name());
      json.writeStringField(TYPE, getAliasedFullQualifiedName(entitySet.getEntityType()));
      if (!entitySet.isIncludeInServiceDocument()) {
        json.writeBooleanField(INCLUDE_IN_SERV_DOC, entitySet.isIncludeInServiceDocument());
      }

      appendNavigationPropertyBindings(json, entitySet);
      appendAnnotations(json, entitySet, null);
      json.writeEndObject();
    }
  }

  private void appendNavigationPropertyBindings(final JsonGenerator json, 
      final EdmBindingTarget bindingTarget) throws SerializerException, IOException {
    if (bindingTarget.getNavigationPropertyBindings() != null && 
        !bindingTarget.getNavigationPropertyBindings().isEmpty()) {
      json.writeObjectFieldStart(NAVIGATION_PROPERTY_BINDING);
      for (EdmNavigationPropertyBinding binding : bindingTarget.getNavigationPropertyBindings()) {
        json.writeStringField(binding.getPath(), binding.getTarget());
      }
      json.writeEndObject();
    }
  }

  private void appendTerms(final JsonGenerator json, final List<EdmTerm> terms) 
      throws SerializerException, IOException {
    for (EdmTerm term : terms) {
      json.writeObjectFieldStart(term.getName());
      json.writeStringField(KIND, Kind.Term.name());

      json.writeStringField(TYPE, getAliasedFullQualifiedName(term.getType()));

      if (term.getBaseTerm() != null) {
        json.writeStringField(BASE_TERM, getAliasedFullQualifiedName(term.getBaseTerm().getFullQualifiedName()));
      }

      if (term.getAppliesTo() != null && !term.getAppliesTo().isEmpty()) {
        String appliesToString = "";
        boolean first = true;
        for (TargetType target : term.getAppliesTo()) {
          if (first) {
            first = false;
            appliesToString = target.toString();
          } else {
            appliesToString = appliesToString + " " + target.toString();
          }
        }
        json.writeStringField(APPLIES_TO, appliesToString);
      }

      // Facets
      if (!term.isNullable()) {
        json.writeBooleanField(NULLABLE, term.isNullable());
      }

      if (term.getDefaultValue() != null) {
        json.writeStringField(DEFAULT_VALUE, term.getDefaultValue());
      }

      if (term.getMaxLength() != null) {
        json.writeNumberField(MAX_LENGTH, term.getMaxLength());
      }

      if (term.getPrecision() != null) {
        json.writeNumberField(PRECISION, term.getPrecision());
      }

      if (term.getScale() != null) {
        json.writeNumberField(SCALE, term.getScale());
      }
      
      appendAnnotations(json, term, null);
      json.writeEndObject();
    }
    
  }

  private void appendFunctions(final JsonGenerator json, 
      final List<EdmFunction> functions) throws SerializerException, IOException {
    Map<String, List<EdmFunction>> functionsMap = new HashMap<>();
    for (EdmFunction function : functions) {
      if (functionsMap.containsKey(function.getName())) {
        List<EdmFunction> actionsWithSpecificActionName = functionsMap.get(function.getName());
        actionsWithSpecificActionName.add(function);
        functionsMap.put(function.getName(), actionsWithSpecificActionName);
      } else {
        List<EdmFunction> functionList = new ArrayList<>();
        functionList.add(function);
        functionsMap.put(function.getName(), functionList);
      }
    }
    
    for (Entry<String, List<EdmFunction>> functionsMapEntry : functionsMap.entrySet()) {
      json.writeArrayFieldStart(functionsMapEntry.getKey());
      List<EdmFunction> functionEntry = functionsMapEntry.getValue();
      for (EdmFunction function : functionEntry) {
        json.writeStartObject();
        json.writeStringField(KIND, Kind.Function.name());
        if (function.getEntitySetPath() != null) {
          json.writeStringField(ENTITY_SET_PATH, function.getEntitySetPath());
        }
        if (function.isBound()) {
          json.writeBooleanField(ISBOUND, function.isBound());
        }

        if (function.isComposable()) {
          json.writeBooleanField(ISCOMPOSABLE, function.isComposable());
        }
        
        appendOperationParameters(json, function);

        appendOperationReturnType(json, function);

        appendAnnotations(json, function, null);

        json.writeEndObject();
      }
      json.writeEndArray();
    }
  }

  private void appendActions(final JsonGenerator json, 
      final List<EdmAction> actions) throws SerializerException, IOException {
    Map<String, List<EdmAction>> actionsMap = new HashMap<>();
    for (EdmAction action : actions) {
      if (actionsMap.containsKey(action.getName())) {
        List<EdmAction> actionsWithSpecificActionName = actionsMap.get(action.getName());
        actionsWithSpecificActionName.add(action);
        actionsMap.put(action.getName(), actionsWithSpecificActionName);
      } else {
        List<EdmAction> actionList = new ArrayList<>();
        actionList.add(action);
        actionsMap.put(action.getName(), actionList);
      }
    }
    for (Entry<String, List<EdmAction>> actionsMapEntry : actionsMap.entrySet()) {
      json.writeArrayFieldStart(actionsMapEntry.getKey());
      List<EdmAction> actionEntry = actionsMapEntry.getValue();
      for (EdmAction action : actionEntry) {
        json.writeStartObject();
        json.writeStringField(KIND, Kind.Action.name());
        if (action.getEntitySetPath() != null) {
          json.writeStringField(ENTITY_SET_PATH, action.getEntitySetPath());
        }
        json.writeBooleanField(ISBOUND, action.isBound());

        appendOperationParameters(json, action);

        appendOperationReturnType(json, action);

        appendAnnotations(json, action, null);

        json.writeEndObject();
      }
      json.writeEndArray();
    }
  }

  private void appendOperationReturnType(final JsonGenerator json, 
      final EdmOperation operation) throws SerializerException, IOException {
    EdmReturnType returnType = operation.getReturnType();
    if (returnType != null) {
      json.writeObjectFieldStart(RETURN_TYPE);
      String returnTypeFqnString;
      if (EdmTypeKind.PRIMITIVE.equals(returnType.getType().getKind())) {
        returnTypeFqnString = getFullQualifiedName(returnType.getType());
      } else {
        returnTypeFqnString = getAliasedFullQualifiedName(returnType.getType());
      }
      json.writeStringField(TYPE, returnTypeFqnString);
      if (returnType.isCollection()) {
        json.writeBooleanField(COLLECTION, returnType.isCollection());
      }
      
      appendReturnTypeFacets(json, returnType);
      json.writeEndObject();
    }
  }

  private void appendReturnTypeFacets(final JsonGenerator json, 
      final EdmReturnType returnType) throws SerializerException, IOException {
    if (!returnType.isNullable()) {
      json.writeBooleanField(NULLABLE, returnType.isNullable());
    }
    if (returnType.getMaxLength() != null) {
      json.writeNumberField(MAX_LENGTH, returnType.getMaxLength());
    }
    if (returnType.getPrecision() != null) {
      json.writeNumberField(PRECISION, returnType.getPrecision());
    }
    if (returnType.getScale() != null) {
      json.writeNumberField(SCALE, returnType.getScale());
    }
  }

  private void appendOperationParameters(final JsonGenerator json, 
      final EdmOperation operation) throws SerializerException, IOException {
    if (!operation.getParameterNames().isEmpty()) {
      json.writeArrayFieldStart(PARAMETER);
    }
    for (String parameterName : operation.getParameterNames()) {
      EdmParameter parameter = operation.getParameter(parameterName);
      json.writeStartObject();
      json.writeStringField(PARAMETER_NAME, parameterName);
      String typeFqnString;
      if (EdmTypeKind.PRIMITIVE.equals(parameter.getType().getKind())) {
        typeFqnString = getFullQualifiedName(parameter.getType());
      } else {
        typeFqnString = getAliasedFullQualifiedName(parameter.getType());
      }
      json.writeStringField(TYPE, typeFqnString);
      if (parameter.isCollection()) {
        json.writeBooleanField(COLLECTION, parameter.isCollection());
      }
      
      appendParameterFacets(json, parameter);

      appendAnnotations(json, parameter, null);
      json.writeEndObject();
    }
    if (!operation.getParameterNames().isEmpty()) {
      json.writeEndArray();
    }
  }

  private void appendParameterFacets(final JsonGenerator json, 
      final EdmParameter parameter) throws SerializerException, IOException {
    if (!parameter.isNullable()) {
      json.writeBooleanField(NULLABLE, parameter.isNullable());
    }
    if (parameter.getMaxLength() != null) {
      json.writeNumberField(MAX_LENGTH, parameter.getMaxLength());
    }
    if (parameter.getPrecision() != null) {
      json.writeNumberField(PRECISION, parameter.getPrecision());
    }
    if (parameter.getScale() != null) {
      json.writeNumberField(SCALE, parameter.getScale());
    }
  }

  private void appendComplexTypes(final JsonGenerator json, 
      final List<EdmComplexType> complexTypes) throws SerializerException, IOException {
    for (EdmComplexType complexType : complexTypes) {
      json.writeObjectFieldStart(complexType.getName());

      json.writeStringField(KIND, Kind.ComplexType.name());
      if (complexType.getBaseType() != null) {
        json.writeStringField(BASE_TYPE, getAliasedFullQualifiedName(complexType.getBaseType()));
      }

      if (complexType.isAbstract()) {
        json.writeBooleanField(ABSTRACT, complexType.isAbstract());
      }

      appendProperties(json, complexType);

      appendNavigationProperties(json, complexType);

      appendAnnotations(json, complexType, null);

      json.writeEndObject();
    }
  }

  private void appendEntityTypes(JsonGenerator json, 
      List<EdmEntityType> entityTypes) throws SerializerException, IOException {
    for (EdmEntityType entityType : entityTypes) {
      json.writeObjectFieldStart(entityType.getName());
      json.writeStringField(KIND, Kind.EntityType.name());
      if (entityType.hasStream()) {
        json.writeBooleanField(HAS_STREAM, entityType.hasStream());
      }

      if (entityType.getBaseType() != null) {
        json.writeStringField(BASE_TYPE, getAliasedFullQualifiedName(entityType.getBaseType()));
      }

      if (entityType.isAbstract()) {
        json.writeBooleanField(ABSTRACT, entityType.isAbstract());
      }

      appendKey(json, entityType);

      appendProperties(json, entityType);

      appendNavigationProperties(json, entityType);

      appendAnnotations(json, entityType, null);

      json.writeEndObject();
    }
  }

  private void appendNavigationProperties(final JsonGenerator json, 
      final EdmStructuredType type) throws SerializerException, IOException {
    List<String> navigationPropertyNames = new ArrayList<>(type.getNavigationPropertyNames());
    if (type.getBaseType() != null) {
      navigationPropertyNames.removeAll(type.getBaseType().getNavigationPropertyNames());
    }
    for (String navigationPropertyName : navigationPropertyNames) {
      EdmNavigationProperty navigationProperty = type.getNavigationProperty(navigationPropertyName);
      json.writeObjectFieldStart(navigationPropertyName);
      json.writeStringField(KIND, Kind.NavigationProperty.name());
      
      json.writeStringField(TYPE, getAliasedFullQualifiedName(navigationProperty.getType()));
      if (navigationProperty.isCollection()) {
        json.writeBooleanField(COLLECTION, navigationProperty.isCollection());
      }
      
      if (!navigationProperty.isNullable()) {
        json.writeBooleanField(NULLABLE, navigationProperty.isNullable());
      }

      if (navigationProperty.getPartner() != null) {
        EdmNavigationProperty partner = navigationProperty.getPartner();
        json.writeStringField(PARTNER, partner.getName());
      }

      if (navigationProperty.containsTarget()) {
        json.writeBooleanField(CONTAINS_TARGET, navigationProperty.containsTarget());
      }

      if (navigationProperty.getReferentialConstraints() != null) {
        for (EdmReferentialConstraint constraint : navigationProperty.getReferentialConstraints()) {
          json.writeObjectFieldStart(REFERENTIAL_CONSTRAINT);
          json.writeStringField(constraint.getPropertyName(), constraint.getReferencedPropertyName());
          for (EdmAnnotation annotation : constraint.getAnnotations()) {
            appendAnnotations(json, annotation, null);
          }
          json.writeEndObject();
        }
      }

      appendAnnotations(json, navigationProperty, null);

      json.writeEndObject();
    }
  }

  private void appendProperties(final JsonGenerator json, 
      final EdmStructuredType type) throws SerializerException, IOException {
    List<String> propertyNames = new ArrayList<>(type.getPropertyNames());
    if (type.getBaseType() != null) {
      propertyNames.removeAll(type.getBaseType().getPropertyNames());
    }
    for (String propertyName : propertyNames) {
      EdmProperty property = type.getStructuralProperty(propertyName);
      json.writeObjectFieldStart(propertyName);
      String fqnString;
      if (property.isPrimitive()) {
        fqnString = getFullQualifiedName(property.getType());
      } else {
        fqnString = getAliasedFullQualifiedName(property.getType());
      }
      json.writeStringField(TYPE, fqnString);
      if (property.isCollection()) {
        json.writeBooleanField(COLLECTION, property.isCollection());
      }

      // Facets
      if (!property.isNullable()) {
        json.writeBooleanField(NULLABLE, property.isNullable());
      }

      if (!property.isUnicode()) {
        json.writeBooleanField(UNICODE, property.isUnicode());
      }

      if (property.getDefaultValue() != null) {
        json.writeStringField(DEFAULT_VALUE, property.getDefaultValue());
      }

      if (property.getMaxLength() != null) {
        json.writeNumberField(MAX_LENGTH, property.getMaxLength());
      }

      if (property.getPrecision() != null) {
        json.writeNumberField(PRECISION, property.getPrecision());
      }

      if (property.getScale() != null) {
        json.writeNumberField(SCALE, property.getScale());
      }
      
      if (property.getSrid() != null) {
          json.writeStringField(SRID, "" + property.getSrid());
      }

      appendAnnotations(json, property, null);
      json.writeEndObject();
    }
  }

  private void appendKey(final JsonGenerator json, 
      final EdmEntityType entityType) throws SerializerException, IOException {
    List<EdmKeyPropertyRef> keyPropertyRefs = entityType.getKeyPropertyRefs();
    if (keyPropertyRefs != null && !keyPropertyRefs.isEmpty()) {
      // Resolve Base Type key as it is shown in derived type
      EdmEntityType baseType = entityType.getBaseType();
      if (baseType != null && baseType.getKeyPropertyRefs() != null && !(baseType.getKeyPropertyRefs().isEmpty())) {
        return;
      }
      json.writeArrayFieldStart(KEY);
      for (EdmKeyPropertyRef keyRef : keyPropertyRefs) {
        
        if (keyRef.getAlias() != null) {
          json.writeStartObject();
          json.writeStringField(keyRef.getAlias(), keyRef.getName());
          json.writeEndObject();
        } else {
          json.writeString(keyRef.getName());
        }
      }
      json.writeEndArray();
    }
  }

  private String getAliasedFullQualifiedName(final EdmType type) {
    FullQualifiedName fqn = type.getFullQualifiedName();
    return getAliasedFullQualifiedName(fqn);
  }
  
  private void appendTypeDefinitions(final JsonGenerator json, 
      final List<EdmTypeDefinition> typeDefinitions) throws SerializerException, IOException {
    for (EdmTypeDefinition definition : typeDefinitions) {
      json.writeObjectFieldStart(definition.getName());
      json.writeStringField(KIND, definition.getKind().name());
      json.writeStringField(UNDERLYING_TYPE, getFullQualifiedName(definition.getUnderlyingType()));
      
      // Facets
      if (definition.getMaxLength() != null) {
        json.writeStringField(MAX_LENGTH, "" + definition.getMaxLength());
      }

      if (definition.getPrecision() != null) {
        json.writeStringField(PRECISION, "" + definition.getPrecision());
      }

      if (definition.getScale() != null) {
        json.writeStringField(SCALE, "" + definition.getScale());
      }
      
      if (definition.getSrid() != null) {
        json.writeStringField(SRID, "" + definition.getSrid());
      }

      appendAnnotations(json, definition, null);
      json.writeEndObject();
    }
  }

  private void appendEnumTypes(JsonGenerator json, List<EdmEnumType> enumTypes) 
      throws SerializerException, IOException {
    for (EdmEnumType enumType : enumTypes) {
      json.writeObjectFieldStart(enumType.getName());
      json.writeStringField(KIND, Kind.EnumType.name());
      json.writeBooleanField(IS_FLAGS, enumType.isFlags());
      json.writeStringField(UNDERLYING_TYPE, getFullQualifiedName(enumType.getUnderlyingType()));

      for (String memberName : enumType.getMemberNames()) {

        EdmMember member = enumType.getMember(memberName);
        if (member.getValue() != null) {
          json.writeStringField(memberName, member.getValue());
        }

        appendAnnotations(json, member, memberName);
      }
      json.writeEndObject();
    }
  }
  
  private void appendAnnotations(JsonGenerator json, 
      final EdmAnnotatable annotatable, String memberName) throws SerializerException, IOException {
    List<EdmAnnotation> annotations = annotatable.getAnnotations();
    if (annotations != null && !annotations.isEmpty()) {
      for (EdmAnnotation annotation : annotations) {
        String termName = memberName != null ? memberName : "";
        if (annotation.getTerm() != null) {
          termName += "@" + getAliasedFullQualifiedName(annotation.getTerm().getFullQualifiedName());
        }
        if (annotation.getQualifier() != null) {
          termName += "#" + annotation.getQualifier();
        } 
        if (annotation.getExpression() == null && termName.length() > 0) {
          json.writeBooleanField(termName, true);
        } else {
          appendExpression(json, annotation.getExpression(), termName);
        }
        appendAnnotations(json, annotation, termName);
      }
    }
  }
  
  private void appendExpression(final JsonGenerator json,
      final EdmExpression expression, String termName) throws SerializerException, IOException {
    if (expression == null) {
      return;
    }
    if (expression.isConstant()) {
      appendConstantExpression(json, expression.asConstant(), termName);
    } else if (expression.isDynamic()) {
      appendDynamicExpression(json, expression.asDynamic(), termName);
    } else {
      throw new IllegalArgumentException("Unkown expressiontype in metadata");
    }
  }
  
  private void appendDynamicExpression(JsonGenerator json, 
      EdmDynamicExpression dynExp, String termName) throws SerializerException, IOException {
    json.writeFieldName(termName);
    switch (dynExp.getExpressionType()) {
    // Logical
    case And:
      appendLogicalOrComparisonExpression(json, dynExp.asAnd());
      break;
    case Or:
      appendLogicalOrComparisonExpression(json, dynExp.asOr());
      break;
    case Not:
      appendNotExpression(json, dynExp.asNot());
      break;
    // Comparison
    case Eq:
      appendLogicalOrComparisonExpression(json, dynExp.asEq());
      break;
    case Ne:
      appendLogicalOrComparisonExpression(json, dynExp.asNe());
      break;
    case Gt:
      appendLogicalOrComparisonExpression(json, dynExp.asGt());
      break;
    case Ge:
      appendLogicalOrComparisonExpression(json, dynExp.asGe());
      break;
    case Lt:
      appendLogicalOrComparisonExpression(json, dynExp.asLt());
      break;
    case Le:
      appendLogicalOrComparisonExpression(json, dynExp.asLe());
      break;
    case AnnotationPath:
      json.writeStartObject();
      json.writeStringField(ANNOTATION_PATH, dynExp.asAnnotationPath().getValue());
      json.writeEndObject();
      break;
    case Apply:
      EdmApply asApply = dynExp.asApply();
      json.writeStartObject();
      json.writeArrayFieldStart(DOLLAR + asApply.getExpressionName());
      for (EdmExpression parameter : asApply.getParameters()) {
        appendExpression(json, parameter, null);
      }
      json.writeEndArray();
      json.writeStringField(DOLLAR + Kind.Function.name(), asApply.getFunction());
      
      appendAnnotations(json, asApply, null);
      json.writeEndObject();
      break;
    case Cast:
      EdmCast asCast = dynExp.asCast();
      json.writeStartObject();
      appendExpression(json, asCast.getValue(), DOLLAR + asCast.getExpressionName());
      json.writeStringField(TYPE, getAliasedFullQualifiedName(asCast.getType()));
     
      if (asCast.getMaxLength() != null) {
        json.writeNumberField(MAX_LENGTH, asCast.getMaxLength());
      }

      if (asCast.getPrecision() != null) {
        json.writeNumberField(PRECISION, asCast.getPrecision());
      }

      if (asCast.getScale() != null) {
        json.writeNumberField(SCALE, asCast.getScale());
      }
      appendAnnotations(json, asCast, null);
      json.writeEndObject();
      break;
    case Collection:
      json.writeStartArray();
      for (EdmExpression item : dynExp.asCollection().getItems()) {
        appendExpression(json, item, null);
      }
      json.writeEndArray();
      break;
    case If:
      EdmIf asIf = dynExp.asIf();
      json.writeStartObject();
      json.writeArrayFieldStart(DOLLAR + asIf.getExpressionName());
      appendExpression(json, asIf.getGuard(), null);
      appendExpression(json, asIf.getThen(), null);
      appendExpression(json, asIf.getElse(), null);
      json.writeEndArray();
      appendAnnotations(json, asIf, null);
      json.writeEndObject();
      break;
    case IsOf:
      EdmIsOf asIsOf = dynExp.asIsOf();
      json.writeStartObject();
      appendExpression(json, asIsOf.getValue(), DOLLAR + asIsOf.getExpressionName());
      
      json.writeStringField(TYPE, getAliasedFullQualifiedName(asIsOf.getType()));

      if (asIsOf.getMaxLength() != null) {
        json.writeNumberField(MAX_LENGTH, asIsOf.getMaxLength());
      }

      if (asIsOf.getPrecision() != null) {
        json.writeNumberField(PRECISION, asIsOf.getPrecision());
      }

      if (asIsOf.getScale() != null) {
        json.writeNumberField(SCALE, asIsOf.getScale());
      }
      appendAnnotations(json, asIsOf, null);
      json.writeEndObject();
      break;
    case LabeledElement:
      EdmLabeledElement asLabeledElement = dynExp.asLabeledElement();
      json.writeStartObject();
      appendExpression(json, asLabeledElement.getValue(), DOLLAR + asLabeledElement.getExpressionName());
      json.writeStringField(NAME, asLabeledElement.getName());
      appendAnnotations(json, asLabeledElement, null);
      json.writeEndObject();
      break;
    case LabeledElementReference:
      EdmLabeledElementReference asLabeledElementReference = dynExp.asLabeledElementReference();
      json.writeStartObject();
      json.writeStringField(DOLLAR + asLabeledElementReference.getExpressionName(), 
          asLabeledElementReference.getValue());
      json.writeEndObject();
      break;
    case Null:
      EdmNull asNull = dynExp.asNull();
      json.writeStartObject();
      json.writeStringField(DOLLAR + asNull.getExpressionName(), null);
      appendAnnotations(json, dynExp.asNull(), null);
      json.writeEndObject();
      break;
    case NavigationPropertyPath:
      EdmNavigationPropertyPath asNavigationPropertyPath = dynExp.asNavigationPropertyPath();
      json.writeStartObject();
      json.writeStringField(DOLLAR + asNavigationPropertyPath.getExpressionName(), 
          asNavigationPropertyPath.getValue());
      json.writeEndObject();
      break;
    case Path:
      EdmPath asPath = dynExp.asPath();
      json.writeStartObject();
      json.writeStringField(DOLLAR + asPath.getExpressionName(), asPath.getValue());
      json.writeEndObject();
      break;
    case PropertyPath:
      EdmPropertyPath asPropertyPath = dynExp.asPropertyPath();
      json.writeStartObject();
      json.writeStringField(DOLLAR + asPropertyPath.getExpressionName(), asPropertyPath.getValue());
      json.writeEndObject();
      break;
    case Record:
      EdmRecord asRecord = dynExp.asRecord();
      json.writeStartObject();
      EdmStructuredType type = asRecord.getType();
      if (type != null) {
        json.writeStringField(TYPE, getAliasedFullQualifiedName(type));
      }
      for (EdmPropertyValue propValue : asRecord.getPropertyValues()) {
        appendExpression(json, propValue.getValue(), propValue.getProperty());
        appendAnnotations(json, propValue, propValue.getProperty());
      }
      appendAnnotations(json, asRecord, null);
      json.writeEndObject();
      break;
    case UrlRef:
      EdmUrlRef asUrlRef = dynExp.asUrlRef();
      json.writeStartObject();
      appendExpression(json, asUrlRef.getValue(), DOLLAR + asUrlRef.getExpressionName());
      appendAnnotations(json, asUrlRef, null);
      json.writeEndObject();
      break;
    default:
      throw new IllegalArgumentException("Unkown ExpressionType for dynamic expression: " + dynExp.getExpressionType());
    }
  }

  private void appendNotExpression(final JsonGenerator json, final EdmNot exp) 
      throws SerializerException, IOException {
    json.writeStartObject();
    appendExpression(json, exp.getLeftExpression(), DOLLAR + exp.getExpressionName());
    appendAnnotations(json, exp, null);
    json.writeEndObject();
  }

  private void appendLogicalOrComparisonExpression(final JsonGenerator json, 
      final EdmLogicalOrComparisonExpression exp) throws SerializerException, IOException {
    json.writeStartObject();
    json.writeArrayFieldStart(DOLLAR + exp.getExpressionName());
    appendExpression(json, exp.getLeftExpression(), null);
    appendExpression(json, exp.getRightExpression(), null);
    json.writeEndArray();
    appendAnnotations(json, exp, null);
    json.writeEndObject();
  }

  private void appendConstantExpression(final JsonGenerator json, 
      final EdmConstantExpression constExp, String termName) throws SerializerException, IOException {
    switch (constExp.getExpressionType()) {
    case Binary: 
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Date:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case DateTimeOffset:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Decimal:
      json.writeObjectFieldStart(termName);      
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Float:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Int:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Duration:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case EnumMember:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Guid:
      json.writeObjectFieldStart(termName);
      json.writeStringField("$" + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case TimeOfDay:
      json.writeObjectFieldStart(termName);
      json.writeStringField(DOLLAR + constExp.getExpressionName(), constExp.getValueAsString());
      json.writeEndObject();
      break;
    case Bool:
      if (termName != null && termName.length() > 0) {
        json.writeBooleanField(termName, Boolean.valueOf(constExp.getValueAsString()));
      } else {
        json.writeBoolean(Boolean.valueOf(constExp.getValueAsString()));
      }
      break;
    case String:
      if (termName != null && termName.length() > 0) {
        json.writeStringField(termName, constExp.getValueAsString());
      } else {
        json.writeString(constExp.getValueAsString());
      }
      break;
    default:
      throw new IllegalArgumentException("Unkown ExpressionType "
          + "for constant expression: " + constExp.getExpressionType());
    }
  }

  private String getAliasedFullQualifiedName(final FullQualifiedName fqn) {
    final String name;
    if (namespaceToAlias.get(fqn.getNamespace()) != null) {
      name = namespaceToAlias.get(fqn.getNamespace()) + "." + fqn.getName();
    } else {
      name = fqn.getFullQualifiedNameAsString();
    }

    return name;
  }
  
  private String getFullQualifiedName(final EdmType type) {
    return type.getFullQualifiedName().getFullQualifiedNameAsString();
  }

  private void appendReference(JsonGenerator json) throws SerializerException, IOException {
    json.writeObjectFieldStart(REFERENCES);
    for (final EdmxReference reference : serviceMetadata.getReferences()) {
      json.writeObjectFieldStart(reference.getUri().toASCIIString());

      List<EdmxReferenceInclude> includes = reference.getIncludes();
      if (!includes.isEmpty()) {
        appendIncludes(json, includes);
      }

      List<EdmxReferenceIncludeAnnotation> includeAnnotations = reference.getIncludeAnnotations();
      if (!includeAnnotations.isEmpty()) {
        appendIncludeAnnotations(json, includeAnnotations);
      }
      json.writeEndObject();
    }
    json.writeEndObject();
  }

  private void appendIncludeAnnotations(JsonGenerator json, 
      List<EdmxReferenceIncludeAnnotation> includeAnnotations) throws SerializerException, IOException {
    json.writeArrayFieldStart(INCLUDE_ANNOTATIONS);
    for (EdmxReferenceIncludeAnnotation includeAnnotation : includeAnnotations) {
      json.writeStartObject();
      json.writeStringField(TERM_NAMESPACE, includeAnnotation.getTermNamespace());
      if (includeAnnotation.getQualifier() != null) {
        json.writeStringField(QUALIFIER, includeAnnotation.getQualifier());
      }
      if (includeAnnotation.getTargetNamespace() != null) {
        json.writeStringField(TARGET_NAMESPACE, includeAnnotation.getTargetNamespace());
      }
      json.writeEndObject();
    }
    json.writeEndArray();
  }

  private void appendIncludes(JsonGenerator json, 
      List<EdmxReferenceInclude> includes) throws SerializerException, IOException {
   json.writeArrayFieldStart(INCLUDE);
   for (EdmxReferenceInclude include : includes) {
     json.writeStartObject();
     json.writeStringField(NAMESPACE, include.getNamespace());
     if (include.getAlias() != null) {
       namespaceToAlias.put(include.getNamespace(), include.getAlias());
       // Reference Aliases are ignored for now since they are not V2 compatible
       json.writeStringField(ALIAS, include.getAlias());
     }
     json.writeEndObject();
   }
   json.writeEndArray();
  }
}
