/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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 com.intellij.psi;

import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
 * Intersection types arise in a process of computing least upper bound.
 *
 * @author ven
 */
public class PsiIntersectionType extends PsiType.Stub {
  private final PsiType[] myConjuncts;

  private PsiIntersectionType(@NotNull PsiType[] conjuncts) {
    super(PsiAnnotation.EMPTY_ARRAY);
    myConjuncts = conjuncts;
  }

  @NotNull
  public static PsiType createIntersection(@NotNull List<PsiType> conjuncts) {
    return createIntersection(conjuncts.toArray(createArray(conjuncts.size())));
  }

  @NotNull
  public static PsiType createIntersection(PsiType... conjuncts) {
    assert conjuncts.length > 0;
    conjuncts = flattenAndRemoveDuplicates(conjuncts);
    if (conjuncts.length == 1) return conjuncts[0];
    return new PsiIntersectionType(conjuncts);
  }

  private static PsiType[] flattenAndRemoveDuplicates(PsiType[] conjuncts) {
    try {
      Set<PsiType> flattened = flatten(conjuncts, ContainerUtil.<PsiType>newLinkedHashSet());
      return flattened.toArray(createArray(flattened.size()));
    }
    catch (NoSuchElementException e) {
      throw new RuntimeException(Arrays.toString(conjuncts), e);
    }
  }

  private static Set<PsiType> flatten(PsiType[] conjuncts, Set<PsiType> types) {
    for (PsiType conjunct : conjuncts) {
      if (conjunct instanceof PsiIntersectionType) {
        PsiIntersectionType type = (PsiIntersectionType)conjunct;
        flatten(type.getConjuncts(), types);
      }
      else {
        types.add(conjunct);
      }
    }
    if (types.size() > 1) {
      PsiType[] array = types.toArray(createArray(types.size()));
      for (Iterator<PsiType> iterator = types.iterator(); iterator.hasNext(); ) {
        PsiType type = iterator.next();

        for (PsiType existing : array) {
          if (type != existing) {
            final boolean allowUncheckedConversion = type instanceof PsiClassType && ((PsiClassType)type).isRaw();
            if (TypeConversionUtil.isAssignable(GenericsUtil.eliminateWildcards(type), 
                                                GenericsUtil.eliminateWildcards(existing), allowUncheckedConversion)) {
              iterator.remove();
              break;
            }
          }
        }
      }
      if (types.isEmpty()) {
        types.add(array[0]);
      }
    }
    return types;
  }

  @NotNull
  public PsiType[] getConjuncts() {
    return myConjuncts;
  }

  @NotNull
  @Override
  public String getPresentableText() {
    return StringUtil.join(myConjuncts, new Function<PsiType, String>() {
      @Override
      public String fun(PsiType psiType) {
        return psiType.getPresentableText();
      }
    }, " & ");
  }

  @NotNull
  @Override
  public String getCanonicalText(boolean annotated) {
    return myConjuncts[0].getCanonicalText(annotated);
  }

  @NotNull
  @Override
  public String getInternalCanonicalText() {
    return StringUtil.join(myConjuncts, new Function<PsiType, String>() {
      @Override
      public String fun(PsiType psiType) {
        return psiType.getInternalCanonicalText();
      }
    }, " & ");
  }

  @Override
  public boolean isValid() {
    for (PsiType conjunct : myConjuncts) {
      if (!conjunct.isValid()) return false;
    }
    return true;
  }

  @Override
  public boolean equalsToText(@NotNull String text) {
    return false;
  }

  @Override
  public <A> A accept(@NotNull PsiTypeVisitor<A> visitor) {
    return visitor.visitIntersectionType(this);
  }

  @Override
  public GlobalSearchScope getResolveScope() {
    return myConjuncts[0].getResolveScope();
  }

  @Override
  @NotNull
  public PsiType[] getSuperTypes() {
    return myConjuncts;
  }

  public PsiType getRepresentative() {
    return myConjuncts[0];
  }

  public boolean equals(final Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof PsiIntersectionType)) return false;
    final PsiType[] first = getConjuncts();
    final PsiType[] second = ((PsiIntersectionType)obj).getConjuncts();
    if (first.length != second.length) return false;
    //positional equality
    for (int i = 0; i < first.length; i++) {
      if (!first[i].equals(second[i])) return false;
    }

    return true;
  }

  public int hashCode() {
    return myConjuncts[0].hashCode();
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("PsiIntersectionType: ");
    for (int i = 0; i < myConjuncts.length; i++) {
      if (i > 0) sb.append(", ");
      sb.append(myConjuncts[i].getPresentableText());
    }
    return sb.toString();
  }
}
