/*
 * 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.EObject;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;

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

/**
 * @author alruiz@google.com (Alex Ruiz)
 */
class OptionDescriptions {

  @Inject private ProtoDescriptorProvider descriptorProvider;
  @Inject private ProtobufElementFinder finder;
  @Inject private ImportedNamesProvider importedNamesProvider;
  @Inject private Imports imports;
  @Inject private LocalNamesProvider localNamesProvider;
  @Inject private PackageResolver packageResolver;
  @Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
  @Inject private ImportUriResolver uriResolver;

  Collection <IEObjectDescription> builtInOptionProperties(BuiltInOption option) {
    ProtoDescriptor descriptor = descriptorProvider.get();
    Collection<Property> properties = descriptor.availableOptionPropertiesFor(option.eContainer());
    if (!properties.isEmpty()) return describe(properties);
    return emptyList();
  }

  Collection <IEObjectDescription> localCustomOptionProperties(EObject root, OptionType optionType) {
    return localCustomOptionProperties(root, optionType, 0);
  }

  private Collection <IEObjectDescription> localCustomOptionProperties(EObject root, OptionType optionType, int level) {
    if (optionType == null) return emptyList();
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (EObject element : root.eContents()) {
      if (isExtendingOptionMessage(element, optionType)) {
        ExtendMessage extend = (ExtendMessage) element;
        for (MessageElement e : extend.getElements()) {
          if (!(e instanceof Property)) continue;
          List<QualifiedName> names = localNamesProvider.namesOf(e);
          int nameCount = names.size();
          for (int i = level; i < nameCount; i++) {
            descriptions.add(create(names.get(i), e));
          }
          descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(e));
        }
        continue;
      }
      if (element instanceof Message) {
        descriptions.addAll(localCustomOptionProperties(element, optionType, level + 1));
      }
    }
    return descriptions;
  }

  Collection<IEObjectDescription> importedCustomOptionProperties(Protobuf root, OptionType optionType) {
    List<Import> allImports = finder.importsIn(root);
    if (allImports.isEmpty()) return emptyList();
    ResourceSet resourceSet = root.eResource().getResourceSet();
    return importedCustomOptionProperties(allImports, finder.packageOf(root), resourceSet, optionType);
  }

  private Collection<IEObjectDescription> importedCustomOptionProperties(List<Import> allImports, Package aPackage,
      ResourceSet resourceSet, OptionType optionType) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (Import anImport : allImports) {
      if (imports.isImportingDescriptor(anImport)) continue;
      Resource importedResource = importedResource(anImport, resourceSet);
      Protobuf importedRoot = finder.rootOf(importedResource);
      if (importedRoot != null) {
        descriptions.addAll(publicImportedCustomOptionProperties(importedRoot, optionType));
        if (arePackagesRelated(aPackage, importedRoot)) {
          descriptions.addAll(localCustomOptionProperties(importedRoot, optionType));
          continue;
        }
      }
      descriptions.addAll(localCustomOptionProperties(importedResource, optionType));
    }
    return descriptions;
  }

  private Resource importedResource(Import anImport, ResourceSet resourceSet) {
    URI importUri = createURI(uriResolver.apply(anImport));
    try {
      return resourceSet.getResource(importUri, true);
    } catch (Throwable t) {
      return null;
    }
  }

  private <T extends Type> Collection<IEObjectDescription> publicImportedCustomOptionProperties(Protobuf root,
      OptionType optionType) {
    List<Import> allImports = finder.publicImportsIn(root);
    if (allImports.isEmpty()) return emptyList();
    ResourceSet resourceSet = root.eResource().getResourceSet();
    return importedCustomOptionProperties(allImports, finder.packageOf(root), resourceSet, optionType);
  }

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

  private Collection<IEObjectDescription> describe(Collection<Property> properties) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    for (Property p : properties) {
      descriptions.add(create(p.getName(), p));
    }
    return descriptions;
  }

  private Collection<IEObjectDescription> localCustomOptionProperties(Resource resource, OptionType optionType) {
    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
    TreeIterator<Object> contents = getAllContents(resource, true);
    while (contents.hasNext()) {
      Object next = contents.next();
      if (!isExtendingOptionMessage(next, optionType)) continue;
      ExtendMessage extend = (ExtendMessage) next;
      for (MessageElement e : extend.getElements()) {
        if (!(e instanceof Property)) continue;
        descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(e));
        for (QualifiedName name : importedNamesProvider.namesOf(e)) {
          descriptions.add(create(name, e));
        }
      }
    }
    return descriptions;
  }

  private boolean isExtendingOptionMessage(Object o, OptionType optionType) {
    if (!(o instanceof ExtendMessage)) return false;
    Message message = messageFrom((ExtendMessage) o);
    if (message == null) return false;
    return optionType.messageName.equals(message.getName());
  }

  private Message messageFrom(ExtendMessage extend) {
    MessageRef ref = extend.getMessage();
    return ref == null ? null : ref.getType();
  }
}
