package jetbrains.mps.baseLanguage.unitTest.execution.client;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import java.util.List;
import jetbrains.mps.baseLanguage.unitTest.behavior.ITestCase__BehaviorDescriptor;
import jetbrains.mps.baseLanguage.unitTest.behavior.ITestable__BehaviorDescriptor;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import org.jetbrains.annotations.NotNull;
import jetbrains.mps.baseLanguage.unitTest.behavior.ITestMethod__BehaviorDescriptor;
import java.util.ArrayList;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import org.jetbrains.annotations.NonNls;

/**
 * Please migrate to TestDescriptor API.
 * 
 * @deprecated 
 */
@Deprecated(since = "2023.1", forRemoval = true)
public class LanguageTestWrapper extends AbstractTestWrapper<SNode> {
  private final ITestNodeWrapper myTestCase;
  private final String myName;
  private final String myQualifiedName;
  private List<ITestNodeWrapper> myMethods;

  @Deprecated
  public LanguageTestWrapper(SNode test) {
    super(test, (boolean) ITestCase__BehaviorDescriptor.canRunInProcess_id5_jSk8paieB.invoke(test), (boolean) ITestable__BehaviorDescriptor.isMpsStartRequired_id2RMg39tmiFh.invoke(test), false);
    myTestCase = null;
    myName = ITestCase__BehaviorDescriptor.getSimpleClassName_idhSQIE8p.invoke(test);
    myQualifiedName = ITestCase__BehaviorDescriptor.getClassName_idhGBnqtL.invoke(test);
    // It used to be TestNodeWrapperFactory.tryWrap for test.getTestMethods(), however, with EditorTestCase being both ITestCase AND ITestMethod,
    // there's no chance for TNWF to guess proper LTW constructor without further refactoring (it ends up with two identical LTW instances, both isTestCase == true),
    // therefore, we use explicit cons for child LTW (used to be a hack 919afafa, that gave method's name if node happens to be ITestMethod).
    // With that, indeed, we loose extensibility of TNWF, but I don't care too much as it's MPS-controlled factory anyway (let alone I doubt there's ever need to
    // have anything else under a wrapper for ITestCase).
    //  Proper fix would be to introduce tryToWrap(ITestNodeWrapper container, node<>) method, that would respect owner testcase explicitly.
    myMethods = ListSequence.fromList(ITestCase__BehaviorDescriptor.getUncommentedTestMethods_id6I8tQNTvi0f.invoke(test)).select((it) -> new LanguageTestWrapper(LanguageTestWrapper.this, it)).ofType(ITestNodeWrapper.class).toList();
  }

  @Deprecated
  public LanguageTestWrapper(@NotNull ITestNodeWrapper testCase, @NotNull SNode testMethod) {
    // perhaps, shall derive MPS requirement form ITestNodeWrapper, but as long as isMpsStartRequired is in ITestable, don't see a reason.
    super(testMethod, testCase.canRunInProcess(), (boolean) ITestable__BehaviorDescriptor.isMpsStartRequired_id2RMg39tmiFh.invoke(testMethod), false);
    myTestCase = testCase;
    myName = ITestMethod__BehaviorDescriptor.getTestName_idhGBohAB.invoke(testMethod);
    myQualifiedName = testCase.getFqName() + '.' + myName;
    myMethods = ListSequence.fromList(new ArrayList<ITestNodeWrapper>(0));
  }

  @Override
  public final boolean isTestCase() {
    return myTestCase == null;
  }

  @Nullable
  @Override
  public ITestNodeWrapper getTestCase() {
    return myTestCase;
  }

  @NotNull
  @Override
  public Iterable<ITestNodeWrapper> getTestMethods() {
    return myMethods;
  }

  @Override
  public int hashCode() {
    // I need this for the EditorTestCase for which two LTW were equal
    return Objects.hash(myNodePointer, isTestCase());
  }

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

    LanguageTestWrapper that = (LanguageTestWrapper) o;
    // I need this for the EditorTestCase for which two LTW were equal
    return myNodePointer.equals(that.myNodePointer) && isTestCase() == that.isTestCase();
  }

  @NonNls
  @Override
  public String getFqName() {
    return myQualifiedName;
  }

  @NonNls
  @Override
  public String getName() {
    return myName;
  }
}
