package jetbrains.mps.kotlin.behavior;

/*Generated by MPS */

import org.jetbrains.mps.openapi.model.SNode;
import java.util.Set;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import java.util.HashSet;
import java.util.List;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.kotlin.api.declaration.ParameterDeclaration;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.smodel.builder.SNodeBuilder;
import org.jetbrains.mps.openapi.language.SProperty;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import org.jetbrains.mps.openapi.language.SConcept;
import org.jetbrains.mps.openapi.language.SInterfaceConcept;
import org.jetbrains.mps.openapi.language.SContainmentLink;

/**
 * Helper functions to initialize a lambda literal from various inputs
 */
public class FunctionTypeToLambdaHelper {
  public static SNode createLambda(Iterable<SNode> parameterTypes) {
    final Set<String> names = SetSequence.fromSet(new HashSet<String>());
    List<SNode> list = Sequence.fromIterable(parameterTypes).select((it) -> {
      String name = IType__BehaviorDescriptor.toString_id4nn3FPlZH$r.invoke(it, ((boolean) true));
      name = ((name == null || name.length() == 0) ? "param" : name.substring(0, 1).toLowerCase() + name.substring(1));
      if (SetSequence.fromSet(names).contains(name)) {
        int index = 0;
        while (SetSequence.fromSet(names).contains(name + (++index))) {
        }
        name = name + index;
      }

      SetSequence.fromSet(names).addElement(name);
      return createVariableDeclaration_pdb775_a5a0a0a0b0a(name, SNodeOperations.copyNode(it));
    }).toList();

    return createLambdaLiteral_pdb775_a3a0(list);
  }

  public static SNode createLambda(Iterable<ParameterDeclaration> parameter, final NodeTypeVarSubs subs) {
    return createLambdaLiteral_pdb775_a0a2(Sequence.fromIterable(parameter).select((it) -> createVariableDeclaration_pdb775_a0a0a0a0a0a0a2(SPropertyOperations.getString(it.getNode(), PROPS.name$MnvL), SNodeOperations.copyNode(subs.expand(it.getType())))).toList());
  }

  private static SNode createVariableDeclaration_pdb775_a5a0a0a0b0a(String p0, SNode p1) {
    SNodeBuilder n0 = new SNodeBuilder().init(CONCEPTS.VariableDeclaration$DF);
    n0.setProperty(PROPS.name$MnvL, p0);
    n0.forChild(LINKS.type$RmkT).initNode(p1, CONCEPTS.IType$Ni, true);
    return n0.getResult();
  }
  private static SNode createLambdaLiteral_pdb775_a3a0(Iterable<? extends SNode> p0) {
    SNodeBuilder n0 = new SNodeBuilder().init(CONCEPTS.LambdaLiteral$Bd);
    n0.forChild(LINKS.parameters$hLEY).initNodeList(p0, CONCEPTS.ILambdaParameter$1h);
    return n0.getResult();
  }
  private static SNode createLambdaLiteral_pdb775_a0a2(Iterable<? extends SNode> p0) {
    SNodeBuilder n0 = new SNodeBuilder().init(CONCEPTS.LambdaLiteral$Bd);
    n0.forChild(LINKS.parameters$hLEY).initNodeList(p0, CONCEPTS.ILambdaParameter$1h);
    return n0.getResult();
  }
  private static SNode createVariableDeclaration_pdb775_a0a0a0a0a0a0a2(String p0, SNode p1) {
    SNodeBuilder n0 = new SNodeBuilder().init(CONCEPTS.VariableDeclaration$DF);
    n0.setProperty(PROPS.name$MnvL, p0);
    n0.forChild(LINKS.type$RmkT).initNode(p1, CONCEPTS.IType$Ni, true);
    return n0.getResult();
  }

  private static final class PROPS {
    /*package*/ static final SProperty name$MnvL = MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x110396eaaa4L, 0x110396ec041L, "name");
  }

  private static final class CONCEPTS {
    /*package*/ static final SConcept VariableDeclaration$DF = MetaAdapterFactory.getConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af571L, "jetbrains.mps.kotlin.structure.VariableDeclaration");
    /*package*/ static final SInterfaceConcept IType$Ni = MetaAdapterFactory.getInterfaceConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af441L, "jetbrains.mps.kotlin.structure.IType");
    /*package*/ static final SConcept LambdaLiteral$Bd = MetaAdapterFactory.getConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af517L, "jetbrains.mps.kotlin.structure.LambdaLiteral");
    /*package*/ static final SInterfaceConcept ILambdaParameter$1h = MetaAdapterFactory.getInterfaceConcept(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af479L, "jetbrains.mps.kotlin.structure.ILambdaParameter");
  }

  private static final class LINKS {
    /*package*/ static final SContainmentLink type$RmkT = MetaAdapterFactory.getContainmentLink(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af571L, 0x28bef6d7551af917L, "type");
    /*package*/ static final SContainmentLink parameters$hLEY = MetaAdapterFactory.getContainmentLink(0x6b3888c1980244d8L, 0x8baff8e6c33ed689L, 0x28bef6d7551af517L, 0x11400bb7909511ebL, "parameters");
  }
}
