package jetbrains.mps.lang.test.generator.rt;

/*Generated by MPS */

import jetbrains.mps.baseLanguage.unitTest.platform.TestDiscoveryParticipant;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import jetbrains.mps.baseLanguage.unitTest.platform.TestDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.baseLanguage.unitTest.platform.TestDiscoveryRequest;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.baseLanguage.unitTest.platform.TestDescriptorBuilder;
import jetbrains.mps.lang.core.behavior.INamedConcept__BehaviorDescriptor;
import jetbrains.mps.baseLanguage.unitTest.platform.SNodeTestSource;
import jetbrains.mps.baseLanguage.unitTest.platform.TestProperties;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SLinkOperations;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import java.util.List;
import java.util.Collections;
import jetbrains.mps.baseLanguage.unitTest.platform.TestPlatform;
import jetbrains.mps.internal.collections.runtime.Sequence;
import org.jetbrains.mps.openapi.language.SConcept;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SContainmentLink;

public enum GeneratorTestDiscoveryParticipants implements TestDiscoveryParticipant {
  GeneratorTest(CONCEPTS.GeneratorTest$C3, true) {
    @Nullable
    @Override
    public Optional<TestDescriptor> discover(@NotNull SNode node, TestDiscoveryRequest request) {
      if (!(SNodeOperations.isInstanceOf(node, CONCEPTS.GeneratorTest$C3))) {
        return Optional.empty();
      }
      final TestDescriptor testContainer = new TestDescriptorBuilder(request.peekContainer()).newTestContainer(INamedConcept__BehaviorDescriptor.getFqName_idhEwIO9y.invoke(SNodeOperations.cast(node, CONCEPTS.GeneratorTest$C3)), SNodeTestSource.of(node)).withProperty(TestProperties.REQUIRES_MPS_PLATFORM, true).add();
      ListSequence.fromList(SLinkOperations.getChildren(SNodeOperations.cast(node, CONCEPTS.GeneratorTest$C3), LINKS.tests$gTrp)).visitAll((it) -> {
        // *the following text was copied from GeneratorTestWrapper verbatim*
        // FIXME this is a hack. I don't want to introduce getMethodName into TestAssertion, and the only information passed during test
        // execution is method name (JUnit's Request/Description), therefore I'm forced to use method name to match ITestNodeWrappers in UI.
        // Perhaps, with JUnit5 there's a way to pass additional identification of a test so that we are not bound to generated method names.
        new TestDescriptorBuilder(testContainer).newTest("testTransformAndMatch" + (SNodeOperations.getIndexInParent(it)), SNodeTestSource.of(it)).add();

      });

      return Optional.of(testContainer);
    }

  };

  private final boolean myRoot;
  private final SAbstractConcept myWrappedConcept;

  GeneratorTestDiscoveryParticipants(SAbstractConcept wrappedConcept, boolean root) {
    myRoot = root;
    myWrappedConcept = wrappedConcept;
  }

  @Override
  public List<SAbstractConcept> sourceConcepts() {
    return Collections.singletonList(myWrappedConcept);
  }
  public static void registerTestDiscoveryParticipants(TestPlatform testPlatform) {
    for (GeneratorTestDiscoveryParticipants factory : Sequence.fromArray(GeneratorTestDiscoveryParticipants.values())) {
      testPlatform.addTestDiscoveryParticipant(factory);
    }
  }

  public static void unregisterTestDiscoveryParticipants(TestPlatform testPlatform) {
    for (GeneratorTestDiscoveryParticipants factory : Sequence.fromArray(GeneratorTestDiscoveryParticipants.values())) {
      testPlatform.removeTestDiscoveryParticipant(factory);
    }
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept GeneratorTest$C3 = MetaAdapterFactory.getConcept(0x68015e26cc4d49dbL, 0x8715b643faea1769L, 0x7b1db36ecf092beL, "jetbrains.mps.lang.test.generator.structure.GeneratorTest");
  }

  private static final class LINKS {
    /*package*/ static final SContainmentLink tests$gTrp = MetaAdapterFactory.getContainmentLink(0x68015e26cc4d49dbL, 0x8715b643faea1769L, 0x7b1db36ecf092beL, 0x7b1db36ecf0d067L, "tests");
  }
}
