/*
 * Copyright (c) 2016 Google Inc.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v1.0 which
 * accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */
package com.google.eclipse.protobuf.scoping;

import static com.google.eclipse.protobuf.util.Tracer.DEBUG_SCOPING;
import static com.google.eclipse.protobuf.validation.ProtobufResourceValidator.getScopeProviderTimingCollector;
import static java.util.Collections.singletonList;

import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameConverter;
import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameProvider;
import com.google.eclipse.protobuf.protobuf.ComplexType;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.ComplexValue;
import com.google.eclipse.protobuf.protobuf.ComplexValueField;
import com.google.eclipse.protobuf.protobuf.CustomFieldOption;
import com.google.eclipse.protobuf.protobuf.CustomOption;
import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.ExtensionFieldName;
import com.google.eclipse.protobuf.protobuf.FieldName;
import com.google.eclipse.protobuf.protobuf.Group;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.LiteralLink;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.NativeFieldOption;
import com.google.eclipse.protobuf.protobuf.NativeOption;
import com.google.eclipse.protobuf.protobuf.OneOf;
import com.google.eclipse.protobuf.protobuf.OptionField;
import com.google.eclipse.protobuf.protobuf.OptionSource;
import com.google.eclipse.protobuf.protobuf.Package;
import com.google.eclipse.protobuf.protobuf.Protobuf;
import com.google.eclipse.protobuf.protobuf.SimpleValueField;
import com.google.eclipse.protobuf.protobuf.TypeLink;
import com.google.eclipse.protobuf.protobuf.ValueField;
import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;
import com.google.inject.Provider;

import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.ImportNormalizer;
import org.eclipse.xtext.util.IResourceScopeCache;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * A scope provider for the Protobuf language.
 *
 * @author atrookey@google.com (Alexander Rookey)
 */
public class ProtobufScopeProvider extends AbstractDeclarativeScopeProvider {

  @Inject private ProtoDescriptorProvider descriptorProvider;
  @Inject private IResourceScopeCache cache;
  @Inject private ProtobufQualifiedNameConverter nameConverter;
  @Inject private ProtobufQualifiedNameProvider nameProvider;

  private ImportNormalizer createImportNormalizerForEObject(EObject element, boolean ignoreCase) {
    QualifiedName name = nameProvider.getFullyQualifiedName(element);
    return getLocalScopeProvider().createImportedNamespaceResolver(name.toString(), ignoreCase);
  }

  private List<ImportNormalizer> createImportNormalizersForComplexType(
      ComplexType complexType, boolean ignoreCase) {
    List<ImportNormalizer> normalizers = new ArrayList<>();
    normalizers.add(createImportNormalizerForEObject(complexType, ignoreCase));
    normalizers.addAll(createImportNormalizersForOneOf(complexType.eContents(), ignoreCase));
    return normalizers;
  }

  private List<ImportNormalizer> createImportNormalizersForOneOf(
      EList<EObject> children, boolean ignoreCase) {
    List<ImportNormalizer> normalizers = new ArrayList<>();
    for (EObject child : children) {
      if (child instanceof OneOf) {
        normalizers.add(createImportNormalizerForEObject(child, ignoreCase));
        normalizers.addAll(createImportNormalizersForOneOf(child.eContents(), ignoreCase));
      }
    }
    return normalizers;
  }

  /**
   * An {@code IndexedElement} can be a MessageField or Group. When scoping types {@code FieldName},
   * {@code LiteralLink}, or {@code OptionField} that are all related to protocol buffer options, a
   * scope can be created by traversing the EMF Model to find a suitable {@code IndexedElement}, and
   * then creating an import normalized scope for the {@code ComplexType} of the {@code
   * MessageField} or {@code Group}.
   *
   * <p>For example: <pre>
   * enum MyEnum {
   *   FOO = 1;
   * }
   * extend google.protobuf.ServiceOptions {
   *   optional MyEnum my_service_option = 50005;
   * }
   * service MyService {
   *   option (my_service_option) = FOO;
   * }
   * </pre>
   *
   * To scope the {@code LiteralLink} {@code FOO} in {@code MyService}, the {@code MessageField}
   * {@code my_service_option} is found by traversing the model. The method
   * createNormalizedScopeForIndexedElement(IndexedElement, EReference) creates and returns an
   * import normalized scope for the type of the {@code MessageField}, {@code MyEnum}.
   */
  private IScope createNormalizedScopeForIndexedElement(
      IndexedElement indexedElement, EReference reference) {
    HashMap<EReference, IScope> scopeMap =
        cache.get(
            indexedElement,
            indexedElement.eResource(),
            new Provider<HashMap<EReference, IScope>>() {
              @Override
              public HashMap<EReference, IScope> get() {
                return new HashMap<>();
              }
            });
    if (!scopeMap.containsKey(reference)) {
      IScope scope = null;
      if (indexedElement instanceof MessageField) {
        TypeLink typeLink = ((MessageField) indexedElement).getType();
        if (typeLink instanceof ComplexTypeLink) {
          ComplexType complexType = ((ComplexTypeLink) typeLink).getTarget();
          scope = getGlobalScopeProvider().getScope(complexType.eResource(), reference);
          List<ImportNormalizer> normalizers =
              createImportNormalizersForComplexType(complexType, false);
          scope = createProtobufImportScope(scope, complexType, reference, normalizers);
        }
      }
      if (indexedElement instanceof Group) {
        Group group = (Group) indexedElement;
        scope = getGlobalScopeProvider().getScope(group.eResource(), reference);
        ImportNormalizer normalizer = createImportNormalizerForEObject(group, false);
        scope = createProtobufImportScope(scope, group, reference, singletonList(normalizer));
      }
      scopeMap.put(reference, scope);
    }
    return scopeMap.get(reference);
  }

  /**
   * Let the local scope provider compute the list of {@link ImportNormalizer}s to be associated with
   * the {@link ProtobufImportScope}.
   */
  private IScope createProtobufImportScope(IScope parent, EObject context, EReference reference) {
    IScope scope = parent;
    if (context.eContainer() == null) {
      scope = getLocalScopeProvider().getResourceScope(scope, context, reference);
    } else {
      scope = createProtobufImportScope(scope, context.eContainer(), reference);
    }
    return getLocalScopeProvider().getLocalElementsScope(scope, context, reference);
  }

  /**
   * Associate the {@link ProtobufImportScope} with the list of {@link ImportNormalizer}s
   * passed as an argument.
   */
  private IScope createProtobufImportScope(
      IScope parent, EObject context, EReference reference, List<ImportNormalizer> normalizers) {
    IScope scope = parent;
    if (context.eContainer() == null) {
      scope = getLocalScopeProvider().getResourceScope(scope, context, reference);
    } else {
      scope = createProtobufImportScope(scope, context.eContainer(), reference, normalizers);
    }
    return getLocalScopeProvider().getLocalElementsScope(scope, context, reference, normalizers);
  }

  /** Returns descriptor associated with the current project. */
  private @Nullable Resource getDescriptorResource(EObject context) {
    IProject project = EResources.getProjectOf(context.eResource());
    ResourceSet resourceSet = context.eResource().getResourceSet();
    ProtoDescriptorProvider.ProtoDescriptorInfo descriptorInfo =
        descriptorProvider.primaryDescriptor(project);
    return resourceSet.getResource(descriptorInfo.location, true);
  }

  /** Returns the global scope provider. */
  private ProtobufImportUriGlobalScopeProvider getGlobalScopeProvider() {
    return getLocalScopeProvider().getGlobalScopeProvider();
  }

  /** Returns the local scope provider. */
  private ProtobufImportedNamespaceAwareLocalScopeProvider getLocalScopeProvider() {
    return (ProtobufImportedNamespaceAwareLocalScopeProvider) super.getDelegate();
  }

  // TODO (atrookey) Create utility for getting package.
  private String getPackageOfResource(Resource resource) {
    return cache.get(
        "Package",
        resource,
        new Provider<String>() {
          @Override
          public String get() {
            Protobuf protobuf;
            if (resource != null && (protobuf = (Protobuf) resource.getContents().get(0)) != null) {
              for (EObject content : protobuf.getElements()) {
                if (content instanceof Package) {
                  return ((Package) content).getImportedNamespace();
                }
              }
            }
            return "";
          }
        });
  }

  @Override
  public IScope getScope(EObject context, EReference reference) {
    if (DEBUG_SCOPING) {
      getScopeProviderTimingCollector().startTimer();
    }
    IScope scope = super.getScope(context, reference);
    if (DEBUG_SCOPING) {
      getScopeProviderTimingCollector().stopTimer();
    }
    return scope;
  }

  /**
   * Scopes the {@code FieldName}.
   *
   * <p>For example: <pre>
   * message FooOptions {
   *   optional int32 opt1 = 1;
   * }
   * extend google.protobuf.FieldOptions {
   *   optional FooOptions foo_options = 1234;
   * }
   * message Bar {
   *   optional int32 b = 1 [(foo_options) = { opt1: 123 }];
   * }
   * </pre>
   *
   * The {@code NormalFieldName} {@code opt1} contains a cross-reference to {@code FooOptions.opt1}.
   */
  public IScope scope_FieldName_target(FieldName fieldName, EReference reference) {
    if (fieldName instanceof ExtensionFieldName) {
      return getLocalScopeProvider().getResourceScope(fieldName.eResource(), reference);
    }
    IndexedElement indexedElement = null;
    OptionSource optionSource = null;
    EObject valueField = fieldName.eContainer();
    if (valueField instanceof ValueField) {
      EObject complexValue = valueField.eContainer();
      if (complexValue instanceof ComplexValue) {
        EObject unknownOption = complexValue.eContainer();
        if (unknownOption instanceof ComplexValueField) {
          indexedElement = ((ComplexValueField) unknownOption).getName().getTarget();
        }
        if (unknownOption instanceof NativeFieldOption) {
          NativeFieldOption nativeFieldOption = (NativeFieldOption) unknownOption;
          optionSource = nativeFieldOption.getSource();
        }
        if (unknownOption instanceof CustomFieldOption) {
          CustomFieldOption customFieldOption = (CustomFieldOption) unknownOption;
          optionSource = customFieldOption.getSource();
        }
        if (unknownOption instanceof NativeOption) {
          NativeOption option = (NativeOption) unknownOption;
          optionSource = option.getSource();
        }
        if (unknownOption instanceof CustomOption) {
          CustomOption option = (CustomOption) unknownOption;
          optionSource = option.getSource();
        }
        if (optionSource != null) {
          indexedElement = optionSource.getTarget();
        }
        if (indexedElement instanceof MessageField) {
          return createNormalizedScopeForIndexedElement(indexedElement, reference);
        }
      }
    }
    return null;
  }

  /**
   * Creates a scope containing elements of type {@code Literal} that can be referenced with their
   * local name only.
   *
   * <p>For example: <pre>
   * enum MyEnum {
   *   FOO = 1;
   * }
   * extend google.protobuf.ServiceOptions {
   *   optional MyEnum my_service_option = 50005;
   * }
   * service MyService {
   *   option (my_service_option) = FOO;
   * }
   * </pre>
   *
   * The {@code LiteralLink} {@code FOO} contains a cross-reference to {@code MyEnum.FOO}.
   */
  public @Nullable IScope scope_LiteralLink_target(LiteralLink literalLink, EReference reference) {
    EObject container = literalLink.eContainer();
    IndexedElement indexedElement = null;
    if (container instanceof DefaultValueFieldOption) {
      container = container.eContainer();
      if (container instanceof IndexedElement) {
        indexedElement = (IndexedElement) container;
      }
    }
    if (container instanceof NativeFieldOption) {
      indexedElement = ((NativeFieldOption) container).getSource().getTarget();
    }
    if (container instanceof NativeOption) {
      indexedElement = ((NativeOption) container).getSource().getTarget();
    }
    if (container instanceof CustomFieldOption) {
      EList<OptionField> fields = ((CustomFieldOption) container).getFields();
      if (!fields.isEmpty()) {
        indexedElement = fields.get(fields.size() - 1).getTarget();
      } else {
        indexedElement = ((CustomFieldOption) container).getSource().getTarget();
      }
    }
    if (container instanceof CustomOption) {
      EList<OptionField> fields = ((CustomOption) container).getFields();
      if (!fields.isEmpty()) {
        indexedElement = fields.get(fields.size() - 1).getTarget();
      } else {
        indexedElement = ((CustomOption) container).getSource().getTarget();
      }
    }
    if (container instanceof SimpleValueField) {
      indexedElement = ((SimpleValueField) container).getName().getTarget();
    }
    return createNormalizedScopeForIndexedElement(indexedElement, reference);
  }

  /**
   * Recursively scopes the {@code OptionField} starting with the {@code OptionSource}.
   *
   * <p>For example: <pre>
   * message Code {
   *   optional double number = 1;
   * }
   * message Type {
   *   optional Code code = 1;
   * }
   * extend proto2.FieldOptions {
   *   optional Type type = 1000;
   * }
   * message Person {
   *   optional bool active = 1 [(type).code.number = 68];
   * }
   * </pre>
   *
   * The {@code OptionField} {@code number} contains a cross-reference to {@code Code.number}.
   */
  public IScope scope_OptionField_target(OptionField optionField, EReference reference) {
    IScope scope = getLocalScopeProvider().getResourceScope(optionField.eResource(), reference);
    EObject customOption = optionField.eContainer();
    if (customOption != null) {
      OptionSource optionSource = null;
      EList<OptionField> fields = null;
      if (customOption instanceof CustomFieldOption) {
        optionSource = ((CustomFieldOption) customOption).getSource();
        fields = ((CustomFieldOption) customOption).getFields();
      }
      if (customOption instanceof CustomOption) {
        optionSource = ((CustomOption) customOption).getSource();
        fields = ((CustomOption) customOption).getFields();
      }
      if (optionSource != null && fields != null) {
        int index = fields.indexOf(optionField);
        if (index < 0 || fields.size() <= index) {
          throw new IllegalArgumentException(
              "index is " + index + " but field.size() is " + fields.size());
        }
        IndexedElement indexedElement = null;
        if (index == 0) {
          indexedElement = optionSource.getTarget();
        } else {
          indexedElement = fields.get(index - 1).getTarget();
        }
        return createNormalizedScopeForIndexedElement(indexedElement, reference);
      }
    }
    return scope;
  }

  /**
   * Creates a scope containing the default options defined in descriptor.proto.
   *
   * <p>For example: <pre>
   * option java_package = "com.example.foo";
   * </pre>
   *
   * The {@code OptionSource} {@code java_package} contains a cross-reference to {@code
   * google.protobuf.FileOptions.java_package} defined in descriptor.proto.
   */
  public IScope scope_OptionSource_target(OptionSource optionSource, EReference reference) {
    String optionType = OptionType.typeOf(optionSource).messageName();
    Resource resource = optionSource.eResource();
    IScope descriptorScope =
        cache.get(
            optionType,
            resource,
            new Provider<IScope>() {
              @Override
              public IScope get() {
                IScope scope = getGlobalScopeProvider().getScope(resource, reference);
                Resource descriptorResource = getDescriptorResource(optionSource);
                String descriptorMessage =
                    getPackageOfResource(descriptorResource)
                        + nameConverter.getDelimiter()
                        + optionType;
                ImportNormalizer normalizer =
                    getLocalScopeProvider()
                        .createImportedNamespaceResolver(descriptorMessage, false);
                scope =
                    createProtobufImportScope(
                        scope,
                        descriptorResource.getContents().get(0),
                        reference,
                        singletonList(normalizer));
                return scope;
              }
            });
    return createProtobufImportScope(descriptorScope, optionSource, reference);
  }
}
