/*
 * Copyright (c) 2011 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 java.util.Collections.emptyList;
import static org.eclipse.emf.common.util.URI.createURI;
import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
import static org.eclipse.xtext.resource.EObjectDescription.create;

import java.util.*;

import org.eclipse.emf.common.util.*;
import org.eclipse.emf.ecore.*;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.naming.*;
import org.eclipse.xtext.resource.*;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.*;

import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.Package;
import com.google.eclipse.protobuf.util.ProtobufElementFinder;
import com.google.inject.Inject;

/**
 * Custom scoping description.
 *
 * @author alruiz@google.com (Alex Ruiz)
 *
 * @see <a href="http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping">Xtext Scoping</a>
 */
public class ProtobufScopeProvider extends AbstractDeclarativeScopeProvider {

  private static final boolean DO_NOT_IGNORE_CASE = false;

  @Inject private ProtobufElementFinder finder;
  @Inject private DescriptorProvider descriptorProvider;
  @Inject private IQualifiedNameProvider nameProvider;
  @Inject private ImportUriResolver uriResolver;
  @Inject private LocalNamesProvider localNamesProvider;
  @Inject private PackageResolver packageResolver;

  @SuppressWarnings("unused")
  IScope scope_TypeReference_type(TypeReference typeRef, EReference reference) {
    Protobuf root = finder.rootOf(typeRef);
    Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
    EObject current = typeRef.eContainer().eContainer(); // get message of the property containing the TypeReference
    while (current != null) {
      descriptions.addAll(typesIn(current));
      current = current.eContainer();
    }
    descriptions.addAll(importedTypes(root, Type.class));
    return createScope(descriptions);
  }

  private Collection<IEObjectDescription> typesIn(EObject root) {
    return children(root, Type.class);
  }

  @SuppressWarnings("unused")
  IScope scope_MessageReference_type(MessageReference msgRef, EReference reference) {
    Protobuf root = finder.rootOf(msgRef);
    Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
    descriptions.addAll(messagesIn(root));
    descriptions.addAll(importedTypes(root, Message.class));
    return createScope(descriptions);
  }

  private Collection<IEObjectDescription> messagesIn(Protobuf root) {
    return children(root, Message.class);
  }

  private <T extends Type> Collection<IEObjectDescription> children(EObject root, Class<T> targetType) {
    return children(root, targetType, 0);
  }

  private <T extends Type> Collection<IEObjectDescription> children(EObject root, Class<T> targetType, int level) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (EObject element : root.eContents()) {
      if (!targetType.isInstance(element)) continue;
      List<QualifiedName> names = localNamesProvider.namesOf(element);
      int nameCount = names.size();
      for (int i = level; i < nameCount; i++) {
        descriptions.add(create(names.get(i), element));
      }
      descriptions.add(create(nameProvider.getFullyQualifiedName(element), element));
      // TODO investigate if groups can have messages, and if so, add those messages to the scope.
      if (element instanceof Message) {
        descriptions.addAll(children(element, targetType, level + 1));
      }
    }
    return descriptions;
  }

  private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
    List<Import> imports = finder.importsIn(root);
    if (imports.isEmpty()) return emptyList();
    Package importRootPackage = finder.packageOf(root);
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (Import anImport : imports) {
      XtextResource imported = importedResource(anImport);
      EObject importedRoot = imported.getParseResult().getRootASTElement();
      if (arePackagesRelated(importRootPackage, importedRoot)) {
        descriptions.addAll(typesIn(importedRoot));
        continue;
      }
      descriptions.addAll(children(imported, targetType));
    }
    return descriptions;
  }

  private XtextResource importedResource(Import anImport) {
    ResourceSet resourceSet = finder.rootOf(anImport).eResource().getResourceSet();
    URI importUri = createURI(uriResolver.apply(anImport));
    return (XtextResource) resourceSet.getResource(importUri, true);
  }

  private boolean arePackagesRelated(Package aPackage, EObject root) {
    Package p = finder.packageOf(root);
    return packageResolver.areRelated(aPackage, p);
  }

  private <T extends Type> Collection<IEObjectDescription> children(XtextResource resource, Class<T> targetType) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    TreeIterator<Object> contents = getAllContents(resource, true);
    while (contents.hasNext()) {
      Object next = contents.next();
      if (!targetType.isInstance(next)) continue;
      T type = targetType.cast(next);
      descriptions.add(create(nameProvider.getFullyQualifiedName(type), type));
    }
    return descriptions;
  }

  @SuppressWarnings("unused")
  IScope scope_LiteralRef_literal(LiteralRef literalRef, EReference reference) {
    EObject container = literalRef.eContainer();
    if (container instanceof Property) {
      Enum enumType = finder.enumTypeOf((Property) container);
      if (enumType != null) return scopeForLiterals(enumType);
    }
    Descriptor descriptor = descriptorProvider.get();
    if (container instanceof Option && descriptor.isOptimizeForOption((Option) container)) {
      Enum optimizedMode = descriptor.optimizedMode();
      return scopeForLiterals(optimizedMode);
    }
    if (container instanceof FieldOption && descriptor.isCTypeOption((FieldOption) container)) {
      Enum cType = descriptor.cType();
      return scopeForLiterals(cType);
    }
    return null;
  }

  private static IScope scopeForLiterals(Enum enumType) {
    Collection<IEObjectDescription> descriptions = describeLiterals(enumType);
    return createScope(descriptions);
  }

  private static Collection<IEObjectDescription> describeLiterals(Enum enumType) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (Literal literal : enumType.getLiterals())
      descriptions.add(create(literal.getName(), literal));
    return descriptions;
  }

  private static IScope createScope(Iterable<IEObjectDescription> descriptions) {
    return new SimpleScope(descriptions, DO_NOT_IGNORE_CASE);
  }
}
