/*
 * Copyright 2007 Sascha Weinreuter
 *
 * Licensed 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.intellij.plugins.relaxNG.model.descriptors;

import com.intellij.openapi.util.Condition;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.Nullable;
import org.kohsuke.rngom.digested.DElementPattern;
import org.kohsuke.rngom.digested.DPattern;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CompositeDescriptor extends RngElementDescriptor {
  private final DElementPattern[] myPatterns;

  CompositeDescriptor(RngNsDescriptor nsDescriptor, DElementPattern pattern, List<DElementPattern> patterns) {
    super(nsDescriptor, pattern);
    myPatterns = patterns.toArray(new DElementPattern[patterns.size()]);
  }

  @Override
  protected XmlElementDescriptor findElementDescriptor(XmlTag childTag) {
    final List<DElementPattern> patterns = new ArrayList<DElementPattern>();
    for (DElementPattern pattern : myPatterns) {
      patterns.addAll(ChildElementFinder.find(2, pattern));
    }
    // TODO: filter out impossible variants:
    /*
      while this needs both variants of <choice>-children
      <element><choice><caret>

      this does not, because <choice> inside <choice> is unambiguous:
      <element><choice><data type="string" /><choice><caret>
     */
    final XmlElementDescriptor d = myNsDescriptor.findDescriptor(childTag, patterns);
    if (d != null) {
      return d;
    }
    return NULL;
  }

  @Override
  public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) {
    final List<XmlElementDescriptor> descriptors = new ArrayList<XmlElementDescriptor>(Arrays.asList(super.getElementsDescriptors(context)));
    for (DElementPattern pattern : myPatterns) {
      final List<DElementPattern> list = ChildElementFinder.find(2, pattern);
      descriptors.addAll(Arrays.asList(myNsDescriptor.convertElementDescriptors(list)));
    }
    return descriptors.toArray(new XmlElementDescriptor[descriptors.size()]);
  }

  @Override
  protected XmlAttributeDescriptor getAttributeDescriptor(String namespace, String localName) {
    final QName qname = new QName(namespace, localName);

    return computeAttributeDescriptor(AttributeFinder.find(qname, myPatterns));
  }

  @Override
  protected XmlAttributeDescriptor[] collectAttributeDescriptors(@Nullable XmlTag context) {
    final QName qName = null;
    final DPattern[] patterns;
    if (qName == null) {
      patterns = myPatterns;
    } else {
      final List<DElementPattern> p = ContainerUtil.findAll(myPatterns, new Condition<DElementPattern>() {
        @Override
        public boolean value(DElementPattern pattern) {
          return pattern.getName().contains(qName);
        }
      });
      patterns = p.toArray(new DPattern[p.size()]);
    }

    return computeAttributeDescriptors(AttributeFinder.find(patterns));
  }

  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    if (!super.equals(o)) return false;

    final CompositeDescriptor that = (CompositeDescriptor)o;

    if (!Arrays.equals(myPatterns, that.myPatterns)) return false;

    return true;
  }

  public int hashCode() {
    int result = super.hashCode();
    result = 31 * result + Arrays.hashCode(myPatterns);
    return result;
  }

  public DElementPattern[] getElementPatterns() {
    return myPatterns;
  }
}
