package jetbrains.mps.kotlin.scopes.signed;

/*Generated by MPS */

import jetbrains.mps.kotlin.scopes.TypeMembersVisitor;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.kotlin.signatures.MemberSignature;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.kotlin.scopes.VisibilityAccess;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.kotlin.api.members.SourcedSignature;
import jetbrains.mps.kotlin.scopes.SignatureFilterImpl;

/**
 * Visitor searching for the first signature matching the one passed in constructor.
 */
public class SignatureSeekerVisitor extends TypeMembersVisitor {
  public SignatureSeekerVisitor(@NotNull MemberSignature signature, SNode contextNode, VisibilityAccess baseAccess) {
    super(new OneSignatureFilter(signature), contextNode, baseAccess);
  }

  @Override
  public boolean enterType(SNode clazz) {
    if (Sequence.fromIterable(this.getMembers()).isNotEmpty()) {
      return false;
    }
    return super.enterType(clazz);
  }

  public SignatureScope.ContainmentStatus getSearchResult(final SNode expectedSource) {
    Iterable<SourcedSignature> members = this.getMembers();
    if (Sequence.fromIterable(members).isEmpty()) {
      return SignatureScope.ContainmentStatus.NO;
    } else if (expectedSource != null && Sequence.fromIterable(members).any((it) -> it.getSource() == expectedSource)) {
      return SignatureScope.ContainmentStatus.YES;
    } else {
      return SignatureScope.ContainmentStatus.SIGNATURE;
    }
  }

  /*package*/ static class OneSignatureFilter extends SignatureFilterImpl<MemberSignature> {
    private final MemberSignature mySignature;
    public OneSignatureFilter(@NotNull MemberSignature signature) {
      super((Class<MemberSignature>) signature.getClass());
      this.mySignature = signature;
    }

    @Override
    protected boolean accept(MemberSignature signature, SNode source) {
      return mySignature.equals(signature);
    }
  }
}
