/*
 * 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 com.google.eclipse.protobuf.scoping.OptionType.typeOf;
import static java.util.Collections.emptySet;

import com.google.eclipse.protobuf.model.util.MessageFields;
import com.google.eclipse.protobuf.model.util.ModelObjects;
import com.google.eclipse.protobuf.model.util.Options;
import com.google.eclipse.protobuf.protobuf.AbstractCustomOption;
import com.google.eclipse.protobuf.protobuf.AbstractOption;
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.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.ExtensibleType;
import com.google.eclipse.protobuf.protobuf.ExtensibleTypeLink;
import com.google.eclipse.protobuf.protobuf.FieldName;
import com.google.eclipse.protobuf.protobuf.Group;
import com.google.eclipse.protobuf.protobuf.GroupElement;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.LiteralLink;
import com.google.eclipse.protobuf.protobuf.MapType;
import com.google.eclipse.protobuf.protobuf.MapTypeLink;
import com.google.eclipse.protobuf.protobuf.Message;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.MessageLink;
import com.google.eclipse.protobuf.protobuf.MessageOptionField;
import com.google.eclipse.protobuf.protobuf.NormalFieldName;
import com.google.eclipse.protobuf.protobuf.OptionField;
import com.google.eclipse.protobuf.protobuf.OptionSource;
import com.google.eclipse.protobuf.protobuf.Protobuf;
import com.google.eclipse.protobuf.protobuf.Rpc;
import com.google.eclipse.protobuf.protobuf.SimpleValueField;
import com.google.eclipse.protobuf.protobuf.Stream;
import com.google.eclipse.protobuf.protobuf.TypeExtension;
import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;

import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.SimpleScope;

import java.util.Collection;
import java.util.Collections;
import java.util.Set;

/**
 * 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 implements ScopeProvider {
  private static final boolean DO_NOT_IGNORE_CASE = false;

  @Inject private ComplexTypeFinderStrategy complexTypeFinderDelegate;
  @Inject private CustomOptionFieldFinder customOptionFieldFinder;
  @Inject private CustomOptionFieldNameFinder customOptionFieldNameFinder;
  @Inject private CustomOptionFinderStrategy customOptionFinderDelegate;
  @Inject private ExtensionFieldNameFinderStrategy extensionFieldNameFinderDelegate;
  @Inject private ExtensionFieldFinderStrategy extensionFieldFinderDelegate;
  @Inject private ProtoDescriptorProvider descriptorProvider;
  @Inject private MessageFieldFinderStrategy messageFieldFinderDelegate;
  @Inject private MessageFields messageFields;
  @Inject private ModelElementFinder modelElementFinder;
  @Inject private ModelObjects modelObjects;
  @Inject private NormalFieldNameFinderStrategy normalFieldNameFinderDelegate;
  @Inject private LiteralDescriptions literalDescriptions;
  @Inject private NativeOptionDescriptions nativeOptionDescriptions;
  @Inject private Options options;

  @SuppressWarnings("unused")
  public IScope scope_ComplexTypeLink_target(ComplexTypeLink link, EReference r) {
    EObject c = link.eContainer();
    if (c instanceof MapType) {
      c = c.eContainer();
    }
    if (c instanceof MapTypeLink) {
      c = c.eContainer();
    }
    if (c instanceof MessageField) {
      MessageField field = (MessageField) c;
      Collection<IEObjectDescription> complexTypes = potentialComplexTypesFor(field);
      return createScope(complexTypes);
    }
    return createEmptyScope();
  }

  @Override public Collection<IEObjectDescription> potentialComplexTypesFor(MessageField field) {
    return modelElementFinder.find(field, complexTypeFinderDelegate, ComplexType.class);
  }

  @SuppressWarnings("unused")
  public IScope scope_ExtensibleTypeLink_target(ExtensibleTypeLink link, EReference r) {
    EObject c = link.eContainer();
    Collection<IEObjectDescription> extensibleTypes =
        modelElementFinder.find(c, complexTypeFinderDelegate, ExtensibleType.class);
    return createScope(extensibleTypes);
  }

  @Override public Collection<IEObjectDescription> potentialExtensibleTypesFor(TypeExtension extension) {
    Protobuf root = modelObjects.rootOf(extension);
    return modelElementFinder.find(root, complexTypeFinderDelegate, ExtensibleType.class);
  }

  @SuppressWarnings("unused")
  public IScope scope_MessageLink_target(MessageLink link, EReference r) {
    Protobuf root = modelObjects.rootOf(link);
    Collection<IEObjectDescription> messages = allMessages(root);
    return createScope(messages);
  }

  @Override public Collection<IEObjectDescription> potentialMessagesFor(Rpc rpc) {
    Protobuf root = modelObjects.rootOf(rpc);
    return allMessages(root);
  }

  @Override public Collection<IEObjectDescription> potentialMessagesFor(Stream stream) {
    Protobuf root = modelObjects.rootOf(stream);
    return allMessages(root);
  }

  private Collection<IEObjectDescription> allMessages(Protobuf root) {
    return modelElementFinder.find(root, complexTypeFinderDelegate, Message.class);
  }

  @SuppressWarnings("unused")
  public IScope scope_LiteralLink_target(LiteralLink link, EReference r) {
    EObject container = link.eContainer();
    Enum anEnum = null;
    if (container instanceof DefaultValueFieldOption) {
      container = container.eContainer();
    }
    if (container instanceof AbstractOption) {
      AbstractOption option = (AbstractOption) container;
      if (options.isNative(option)) {
        IProject project = EResources.getProjectOf(option.eResource());
        ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor(project);
        IndexedElement e = options.rootSourceOf(option);
        anEnum = descriptor.enumTypeOf((MessageField) e);
      }
    }
    if (container instanceof AbstractCustomOption) {
      AbstractCustomOption option = (AbstractCustomOption) container;
      container = options.sourceOf(option);
    }
    if (container instanceof SimpleValueField) {
      SimpleValueField field = (SimpleValueField) container;
      container = field.getName().getTarget();
    }
    if (container instanceof MessageField) {
      anEnum = messageFields.enumTypeOf((MessageField) container);
    }
    return createScope(literalDescriptions.literalsOf(anEnum));
  }

  @SuppressWarnings("unused")
  public IScope scope_OptionSource_target(OptionSource source, EReference r) {
    EObject c = source.eContainer();
    if (c instanceof AbstractOption) {
      AbstractOption option = (AbstractOption) c;
      if (options.isNative(option)) {
        return createScope(nativeOptionDescriptions.sources(option));
      }
    }
    if (c instanceof AbstractCustomOption) {
      AbstractCustomOption option = (AbstractCustomOption) c;

      if (c instanceof GroupElement) {
        EObject container = c.eContainer();
        if (container instanceof Group) {
          OptionType optionType = OptionType.findOptionTypeForLevelOf(container.eContainer());
          return createScope(optionType != null 
              ? modelElementFinder.find(option, customOptionFinderDelegate, optionType)
              : Collections.<IEObjectDescription>emptySet());
        }
      }

      return createScope(potentialSourcesFor(option));
    }
    Set<IEObjectDescription> descriptions = emptySet();
    return createScope(descriptions);
  }

  @Override public Collection<IEObjectDescription> potentialSourcesFor(AbstractCustomOption option) {
    OptionType optionType = typeOf((AbstractOption) option);
    Collection<IEObjectDescription> descriptions = emptySet();
    if (optionType != null) {
      descriptions = modelElementFinder.find(option, customOptionFinderDelegate, optionType);
    }
    return descriptions;
  }

  @SuppressWarnings("unused")
  public IScope scope_OptionField_target(OptionField field, EReference r) {
    return createScope(allPossibleSourcesOf(field));
  }

  private Collection<IEObjectDescription> allPossibleSourcesOf(OptionField field) {
    if (field == null) {
      return emptySet();
    }
    EObject container = field.eContainer();
    if (container instanceof AbstractCustomOption) {
      AbstractCustomOption option = (AbstractCustomOption) container;
      if (field instanceof MessageOptionField) {
        return customOptionFieldFinder.findOptionFields(option, messageFieldFinderDelegate, field);
      }
      return customOptionFieldFinder.findOptionFields(option, extensionFieldFinderDelegate, field);
    }
    return emptySet();
  }

  @Override public Collection<IEObjectDescription> potentialMessageFieldsFor(AbstractCustomOption option) {
    return customOptionFieldFinder.findOptionFields(option, messageFieldFinderDelegate);
  }

  @Override public Collection<IEObjectDescription> potentialExtensionFieldsFor(AbstractCustomOption option) {
    return customOptionFieldFinder.findOptionFields(option, extensionFieldFinderDelegate);
  }

  @SuppressWarnings("unused")
  public IScope scope_FieldName_target(FieldName name, EReference r) {
    return createScope(findSources(name));
  }

  private Collection<IEObjectDescription> findSources(FieldName name) {
    ComplexValue value = container(name);
    if (value == null) {
      return emptySet();
    }
    if (name instanceof NormalFieldName) {
      return potentialNormalFieldNames(value);
    }
    return potentialExtensionFieldNames(value);
  }

  private ComplexValue container(FieldName name) {
    EObject container = name;
    while (container != null) {
      if (container instanceof ComplexValue) {
        return (ComplexValue) container;
      }
      container = container.eContainer();
    }
    return null;
  }

  @Override public Collection<IEObjectDescription> potentialNormalFieldNames(ComplexValue value) {
    return customOptionFieldNameFinder.findFieldNamesSources(value, normalFieldNameFinderDelegate);
  }

  @Override public Collection<IEObjectDescription> potentialExtensionFieldNames(ComplexValue value) {
    return customOptionFieldNameFinder.findFieldNamesSources(value, extensionFieldNameFinderDelegate);
  }

  private static IScope createEmptyScope() {
    Set<IEObjectDescription> descriptions = emptySet();
    return createScope(descriptions);
  }

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