// Copyright (c) 2026, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:test_case_selector/test_case_selector.dart';

import '../test_util/test_util.dart';

const _copyrightHeader = '''
// Copyright (c) 2026, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
''';

// The kind of top level type under test.
enum TopLevelKind { class_, interface, enum_, record }

// The member inside the top level declaration.
enum Member { field, method, constructor, initializer }

// Java supports nesting types inside other types. These are all the nestable
// types. Nested classes can either be static or non-static. The nested type is
// pretty standalone, and not affected by any of the below enums.
enum NestedKind { none, innerClass, staticClass, interface, enum_, record }

// Modifier applied to the top level type.
enum TopLevelModifier { none, final_, sealed }

// Modifier applied to the member.
enum MemberModifier {
  none,
  static_,
  final_,
  abstract_,
  default_,
  synchronized,
  throws,
  transient,
  volatile,
  native
}

// For members with params, test different numbers of params.
enum ParamCount { zero, one, two }

// Some member names are special cased inside JNIgen, so test those.
enum MemberName { any, getFoo, setFoo, isFoo }

// Affects what the top level type declaration inherits from.
enum Inheritance {
  none,
  extends_,
  implements_,
  multipleImplements,
  extendsGenericSpecialized,
  extendsGenericUnspecialized,
  diamond,
  complexDag
}

// The generic type params of the top level type.
enum Generics { none, oneParam, twoParams, upperBound, lowerBound, wildcard }

// The generic type params of the member.
enum MemberGenerics {
  none,
  oneParam,
  twoParams,
  upperBound,
  lowerBound,
  wildcard
}

// The type of the member. For constructors this is the type of the first arg,
// and for methods this is the type of the first arg and the return type.
enum MemberType {
  void_,
  boolean_,
  char_,
  int_,
  long_,
  short_,
  float_,
  double_,
  byte_,
  object,
  string,
  typeParam,
  memberTypeParam,
  list,
  set,
  map,
  customObject,
  customInterface,
  customEnum,
  customRecord,
  nestedCustom
}

// Whether the MemberType is also an array.
enum IsArray { no, yes }

// Whether the MemberType is nullable.
enum MemberNullability { none, nullable, nonnull }

// Whether the Generics and MemberGenerics are nullable.
enum GenericNullability { none, nullable, nonnull }

void generateJava() {
  final selector = TestCaseSelector(
    dimensions: {
      TopLevelKind: TopLevelKind.values,
      Member: Member.values,
      NestedKind: NestedKind.values,
      TopLevelModifier: TopLevelModifier.values,
      MemberModifier: MemberModifier.values,
      ParamCount: ParamCount.values,
      MemberName: MemberName.values,
      Inheritance: Inheritance.values,
      Generics: Generics.values,
      MemberGenerics: MemberGenerics.values,
      MemberType: MemberType.values,
      IsArray: IsArray.values,
      MemberNullability: MemberNullability.values,
      GenericNullability: GenericNullability.values,
    },
    interactionGroups: [
      // Test that each member works in each top level type.
      {TopLevelKind, Member},
      // The top level type and modifier affect what kind of nesting is allowed.
      {TopLevelKind, NestedKind, TopLevelModifier},
      // Inheritance and generics can interact in weird ways.
      {TopLevelKind, Inheritance, Generics},
      // So can top level generics and member generics.
      {TopLevelKind, Generics, MemberGenerics},
      // The member name special casing is affected by modifiers and generics.
      {Member, MemberModifier, MemberName, MemberGenerics},
      // All member kinds should work with all param counts.
      {Member, ParamCount},
      // All member types should all be array-able and nullable-able.
      {MemberType, IsArray, MemberNullability},
      // Make sure MemberType.memberTypeParam touches all members and generics.
      {Member, MemberGenerics, MemberType},
      // Test that generics nullability works with both kinds of generics.
      {Generics, MemberGenerics, GenericNullability},
    ],
    isValid: (tc) {
      final top = tc.get<TopLevelKind>();
      final member = tc.get<Member>();
      final modifier = tc.get<TopLevelModifier>();
      final mod = tc.get<MemberModifier>();
      final name = tc.get<MemberName>();
      final inheritance = tc.get<Inheritance>();
      final generics = tc.get<Generics>();
      final memberGenerics = tc.get<MemberGenerics>();
      final type = tc.get<MemberType>();
      final paramCount = tc.get<ParamCount>();
      final isArray = tc.get<IsArray>();
      final memberNullability = tc.get<MemberNullability>();
      final genericNullability = tc.get<GenericNullability>();

      // Basic Java constraints
      if (type == MemberType.void_ && isArray == IsArray.yes) {
        return false;
      }
      if (type == MemberType.void_ &&
          memberNullability != MemberNullability.none) {
        return false;
      }
      if (isArray == IsArray.no &&
          memberNullability != MemberNullability.none &&
          isPrimitive(type)) {
        return false;
      }

      if (genericNullability != GenericNullability.none) {
        if (generics == Generics.none &&
            memberGenerics == MemberGenerics.none &&
            inheritance != Inheritance.extendsGenericSpecialized &&
            inheritance != Inheritance.extendsGenericUnspecialized) {
          return false;
        }
      }

      if (memberGenerics != MemberGenerics.none) {
        if (member != Member.method && member != Member.constructor) {
          return false;
        }
      }

      if (top == TopLevelKind.interface) {
        if (member == Member.constructor || member == Member.initializer) {
          return false;
        }
        if (modifier == TopLevelModifier.final_) {
          return false;
        }
      }
      if (modifier == TopLevelModifier.final_ &&
          mod == MemberModifier.abstract_) {
        return false;
      }
      if (top == TopLevelKind.enum_ || top == TopLevelKind.record) {
        if (inheritance != Inheritance.none &&
            inheritance != Inheritance.implements_) {
          return false;
        }
        if (modifier == TopLevelModifier.final_ ||
            modifier == TopLevelModifier.sealed) {
          return false;
        }
      }
      if (top == TopLevelKind.enum_) {
        if (mod == MemberModifier.abstract_ || generics != Generics.none) {
          return false;
        }
      }

      if (modifier == TopLevelModifier.sealed) {
        if (mod == MemberModifier.abstract_) {
          return false;
        }
        if (top == TopLevelKind.interface && member == Member.method) {
          if (mod != MemberModifier.default_ && mod != MemberModifier.static_) {
            return false;
          }
        }
        if (member == Member.constructor && paramCount != ParamCount.zero) {
          return false;
        }
        if (inheritance != Inheritance.none) {
          return false;
        }
        if (memberGenerics != MemberGenerics.none) {
          return false;
        }
      }

      if (generics == Generics.lowerBound || generics == Generics.wildcard) {
        return false;
      }
      if (memberGenerics == MemberGenerics.lowerBound ||
          memberGenerics == MemberGenerics.wildcard) {
        return false;
      }

      if (top == TopLevelKind.record) {
        if (member == Member.initializer ||
            memberGenerics != MemberGenerics.none) {
          return false;
        }
      }

      if (mod != MemberModifier.none) {
        if (mod == MemberModifier.final_) {
          if (member == Member.constructor || member == Member.initializer) {
            return false;
          }
          if (top == TopLevelKind.interface && member == Member.method) {
            return false;
          }
        }
        if (mod == MemberModifier.transient || mod == MemberModifier.volatile) {
          if (member != Member.field || top == TopLevelKind.interface) {
            return false;
          }
        }
        if (mod == MemberModifier.throws && member != Member.method) {
          return false;
        }
        if (member == Member.field) {
          const fieldModifiers = {
            MemberModifier.static_,
            MemberModifier.final_,
            MemberModifier.transient,
            MemberModifier.volatile,
          };
          if (!fieldModifiers.contains(mod)) {
            return false;
          }
        }
        if (member == Member.initializer && mod != MemberModifier.static_) {
          return false;
        }
        if (member == Member.constructor &&
            {
              MemberModifier.abstract_,
              MemberModifier.native,
              MemberModifier.default_,
              MemberModifier.static_,
              MemberModifier.synchronized,
              MemberModifier.throws,
              MemberModifier.final_,
            }.contains(mod)) {
          return false;
        }
      }
      if (mod == MemberModifier.default_ && top != TopLevelKind.interface) {
        return false;
      }

      if (name != MemberName.any && member != Member.method) {
        return false;
      }

      if (type == MemberType.void_ && member != Member.method) {
        return false;
      }
      if (top == TopLevelKind.record && type == MemberType.void_) {
        return false;
      }
      if (type == MemberType.void_ && paramCount != ParamCount.zero) {
        return false;
      }

      if (mod == MemberModifier.static_) {
        final useMemberScope = memberGenerics != MemberGenerics.none &&
            (type == MemberType.memberTypeParam ||
                memberGenerics == MemberGenerics.lowerBound ||
                memberGenerics == MemberGenerics.wildcard);

        if (!useMemberScope && generics != Generics.none) {
          const genericTypes = {
            MemberType.list,
            MemberType.set,
            MemberType.map,
            MemberType.customObject,
            MemberType.customInterface,
            MemberType.customRecord,
            MemberType.nestedCustom,
            MemberType.typeParam,
          };
          if (genericTypes.contains(type)) {
            return false;
          }
        }
      }

      if (type == MemberType.typeParam) {
        if (generics == Generics.none) {
          return false;
        }
        if (top == TopLevelKind.interface && member == Member.field) {
          return false;
        }
      }

      if (top == TopLevelKind.interface && member == Member.field) {
        if (generics != Generics.none) {
          const genericTypes = {
            MemberType.list,
            MemberType.set,
            MemberType.map,
            MemberType.customObject,
            MemberType.nestedCustom,
          };
          if (genericTypes.contains(type)) {
            return false;
          }
        }
      }

      if (type == MemberType.memberTypeParam) {
        if (memberGenerics == MemberGenerics.none) {
          return false;
        }
        if (member == Member.field || top == TopLevelKind.record) {
          return false;
        }
      }

      return true;
    },
  );

  final testCases = selector.select();
  print('Generated ${testCases.length} test cases.');

  final javaDir = Directory(p.join(pkgDir, 'test', 'large_java_test', 'java'));
  if (javaDir.existsSync()) {
    javaDir.deleteSync(recursive: true);
  }
  javaDir.createSync(recursive: true);

  writeCoreClasses(javaDir);

  final outputDir = Directory(p.join(javaDir.path, 'com', 'example'));
  outputDir.createSync(recursive: true);

  for (var i = 0; i < testCases.length; i++) {
    final tc = testCases[i];
    final className = 'TestClass${i.toString().padLeft(3, '0')}';
    final sb = StringBuffer();
    sb.writeln(_copyrightHeader);
    sb.writeln('package com.example;');
    sb.writeln('import java.util.*;');
    sb.writeln('import org.jetbrains.annotations.Nullable;');
    sb.writeln('import org.jetbrains.annotations.NotNull;');
    sb.writeln();
    for (final line in tc.toString().split(', ')) {
      sb.writeln('// $line');
    }
    generateTestCase(sb, className, tc);

    final file = File(p.join(outputDir.path, '$className.java'));
    file.writeAsStringSync(sb.toString());
  }

  print('Wrote files to ${outputDir.path}');
}

void writeCoreClasses(Directory baseDir) {
  final coreClasses = {
    'Nullable': '''
package org.jetbrains.annotations;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
public @interface Nullable {}
''',
    'NotNull': '''
package org.jetbrains.annotations;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
public @interface NotNull {}
''',
    'GrandParent': '''
public class GrandParent {
  public void grandParentMethod() {}
}
''',
    'OtherInterface': '''
public interface OtherInterface {
  void otherInterfaceMethod();
}
''',
    'GenericParent': '''
public class GenericParent<T> {
  public void genericParentMethod(T t) {}
}
''',
    'GenericInterface': '''
public interface GenericInterface<T> {
  T genericInterfaceMethod(T t);
}
''',
    'BaseInterface': '''
public interface BaseInterface {
  int BASE_FIELD = 0;
  void baseMethod();
}
''',
    'DiamondLeft': '''
public interface DiamondLeft extends BaseInterface {
  int LEFT_FIELD = 1;
  void leftMethod();
  @Override
  default void baseMethod() {}
}
''',
    'DiamondRight': '''
public interface DiamondRight extends BaseInterface {
  int RIGHT_FIELD = 2;
  void rightMethod();
  @Override
  default void baseMethod() {}
}
''',
    'DagA': '''
public interface DagA {
  int A_FIELD = 3;
  void aMethod();
}
''',
    'DagB': '''
public interface DagB extends DagA {
  int B_FIELD = 4;
  void bMethod();
}
''',
    'DagC': '''
public interface DagC extends DagA, DagB {
  int C_FIELD = 5;
  void cMethod();
}
''',
    'DagD': '''
public interface DagD extends DagA, DagB, DagC {
  int D_FIELD = 6;
  void dMethod();
}
''',
    'DagE': '''
public interface DagE extends DagB, DagD {
  int E_FIELD = 7;
  void eMethod();
}
''',
    'CustomRecord': '''
public record CustomRecord<T>(T x, String y) {}
''',
    'CustomObject': '''
public class CustomObject<T> {
  public T value;
  public CustomObject(T value) { this.value = value; }
}
''',
    'CustomInterface': '''
public interface CustomInterface<T> {
  T getValue();
}
''',
    'CustomEnum': '''
public enum CustomEnum {
  V1, V2
}
''',
    'NestedCustom': '''
public class NestedCustom<T, U> {
  public class Nested<V> {
    public T t;
    public U u;
    public V v;
  }
}
''',
  };

  for (final entry in coreClasses.entries) {
    final content = entry.value.trim();
    final isOrgJetbrains =
        content.startsWith('package org.jetbrains.annotations;');
    final relativePath = isOrgJetbrains
        ? 'org/jetbrains/annotations/${entry.key}.java'
        : 'com/example/${entry.key}.java';
    final file = File(p.join(baseDir.path, relativePath));
    file.parent.createSync(recursive: true);

    final packageLine =
        content.startsWith('package ') ? '' : 'package com.example;\n\n';
    file.writeAsStringSync('''
$_copyrightHeader
$packageLine$content
''');
  }
}

void generateTestCase(StringBuffer sb, String className, TestCase tc) {
  final top = tc.get<TopLevelKind>();
  final member = tc.get<Member>();
  final nested = tc.get<NestedKind>();
  final modifier = tc.get<TopLevelModifier>();
  final mod = tc.get<MemberModifier>();
  final paramCount = tc.get<ParamCount>();
  final name = tc.get<MemberName>();
  final inheritance = tc.get<Inheritance>();
  final generics = tc.get<Generics>();
  final memberGenerics = tc.get<MemberGenerics>();
  final typeKind = tc.get<MemberType>();
  final isArray = tc.get<IsArray>();
  final memberNullability = tc.get<MemberNullability>();
  final genericNullability = tc.get<GenericNullability>();

  final typeStr = getJavaType(typeKind, isArray == IsArray.yes, generics,
      memberGenerics, memberNullability, genericNullability);
  final inheritanceStr =
      getInheritanceStr(inheritance, top, genericNullability);
  final genStr = getGenericsStr(generics, genericNullability);
  final typeParamsStr = getTypeParamsStr(generics);
  final memberGenStr = getMemberGenericsStr(memberGenerics, genericNullability);
  final topModStr = getTopLevelModifierStr(modifier, mod);
  final kind = getTopLevelKindStr(top);
  final params = getParamsStr(paramCount, typeStr);

  if (top == TopLevelKind.record) {
    sb.write('''
public record $className$genStr($typeStr field) $inheritanceStr {
${getInheritanceMethodsStr(inheritance, top)}}
''');
    return;
  }

  sb.write('''
public $topModStr$kind $className$genStr $inheritanceStr {
''');

  if (top == TopLevelKind.enum_) {
    sb.writeln(getEnumConstantsStr(member, paramCount, typeStr));
  }

  sb.write(getInheritanceMethodsStr(inheritance, top));

  sb.write(switch (member) {
    Member.field => getFieldStr(top, mod, typeStr),
    Member.method =>
      getMethodStr(top, mod, memberGenStr, typeStr, name, params),
    Member.constructor =>
      getConstructorStr(top, memberGenStr, className, params),
    Member.initializer => getInitializerStr(mod),
  });

  if (nested != NestedKind.none) {
    sb.writeln(getNestedStr(nested));
  }

  if (modifier == TopLevelModifier.sealed) {
    final keyword = top == TopLevelKind.interface ? 'implements' : 'extends';
    sb.write('''
  public static final class Sub$genStr $keyword $className$typeParamsStr {}
''');
  }

  sb.writeln('}');
}

String getInheritanceStr(
    Inheritance inheritance, TopLevelKind top, GenericNullability gn) {
  final g = getGenericNullabilityStr(gn);
  switch (inheritance) {
    case Inheritance.none:
      return '';
    case Inheritance.extends_:
      if (top == TopLevelKind.interface) return ' extends OtherInterface';
      if (top == TopLevelKind.record) return '';
      return ' extends GrandParent';
    case Inheritance.implements_:
      if (top == TopLevelKind.interface) return ' extends OtherInterface';
      return ' implements OtherInterface';
    case Inheritance.multipleImplements:
      if (top == TopLevelKind.interface) {
        return ' extends OtherInterface, BaseInterface';
      }
      return ' implements OtherInterface, BaseInterface';
    case Inheritance.extendsGenericSpecialized:
      if (top == TopLevelKind.interface) {
        return ' extends GenericInterface<${g}String>';
      }
      if (top == TopLevelKind.record) {
        return ' implements GenericInterface<${g}String>';
      }
      return ' extends GenericParent<${g}String>';
    case Inheritance.extendsGenericUnspecialized:
      if (top == TopLevelKind.interface) return ' extends GenericInterface';
      if (top == TopLevelKind.record) return ' implements GenericInterface';
      return ' extends GenericParent';
    case Inheritance.diamond:
      if (top == TopLevelKind.interface) {
        return ' extends DiamondLeft, DiamondRight';
      }
      return ' implements DiamondLeft, DiamondRight';
    case Inheritance.complexDag:
      if (top == TopLevelKind.interface) {
        return ' extends DagA, DagD, DagE';
      }
      return ' implements DagA, DagD, DagE';
  }
}

String getInheritanceMethodsStr(Inheritance inheritance, TopLevelKind top) {
  final sb = StringBuffer();
  final isInterface = top == TopLevelKind.interface;

  void add(String decl, [String body = '{}']) {
    if (isInterface) {
      sb.write('''
  @Override
  default $decl $body
''');
    } else {
      sb.write('''
  @Override
  public $decl $body
''');
    }
  }

  switch (inheritance) {
    case Inheritance.none:
      break;
    case Inheritance.extends_:
      if (top == TopLevelKind.interface) {
        add('void otherInterfaceMethod()');
      } else if (top != TopLevelKind.record) {
        add('void grandParentMethod()');
      }
      break;
    case Inheritance.implements_:
      add('void otherInterfaceMethod()');
      break;
    case Inheritance.multipleImplements:
      add('void otherInterfaceMethod()');
      add('void baseMethod()');
      break;
    case Inheritance.extendsGenericSpecialized:
      if (top == TopLevelKind.interface || top == TopLevelKind.record) {
        add('String genericInterfaceMethod(String t)', ' { return t; }');
      } else {
        add('void genericParentMethod(String t)');
      }
      break;
    case Inheritance.extendsGenericUnspecialized:
      if (top == TopLevelKind.interface || top == TopLevelKind.record) {
        add('Object genericInterfaceMethod(Object t)', ' { return t; }');
      } else {
        add('void genericParentMethod(Object t)');
      }
      break;
    case Inheritance.diamond:
      add('void baseMethod()');
      add('void leftMethod()');
      add('void rightMethod()');
      break;
    case Inheritance.complexDag:
      add('void aMethod()');
      add('void bMethod()');
      add('void cMethod()');
      add('void dMethod()');
      add('void eMethod()');
      break;
  }
  return sb.toString();
}

String getGenericNullabilityStr(GenericNullability gn) {
  return switch (gn) {
    GenericNullability.none => '',
    GenericNullability.nullable => '@Nullable ',
    GenericNullability.nonnull => '@NotNull ',
  };
}

String getMemberNullabilityStr(MemberNullability mn) {
  return switch (mn) {
    MemberNullability.none => '',
    MemberNullability.nullable => '@Nullable ',
    MemberNullability.nonnull => '@NotNull ',
  };
}

String getGenericsStr(Generics generics, GenericNullability gn) {
  final g = getGenericNullabilityStr(gn);
  return switch (generics) {
    Generics.none => '',
    Generics.oneParam => '<${g}T>',
    Generics.twoParams => '<${g}T, ${g}U>',
    Generics.upperBound => '<${g}T extends Number>',
    Generics.lowerBound => '<${g}T>',
    Generics.wildcard => '<${g}T>',
  };
}

String getTypeParamsStr(Generics generics) {
  return switch (generics) {
    Generics.none => '',
    Generics.oneParam => '<T>',
    Generics.twoParams => '<T, U>',
    _ => '<T>',
  };
}

String getMemberGenericsStr(
    MemberGenerics memberGenerics, GenericNullability gn) {
  final g = getGenericNullabilityStr(gn);
  return switch (memberGenerics) {
    MemberGenerics.none => '',
    MemberGenerics.oneParam => '<${g}S> ',
    MemberGenerics.twoParams => '<${g}S, ${g}V> ',
    MemberGenerics.upperBound => '<${g}S extends Number> ',
    MemberGenerics.lowerBound => '<${g}S> ',
    MemberGenerics.wildcard => '<${g}S> ',
  };
}

String getTopLevelModifierStr(TopLevelModifier modifier, MemberModifier mod) {
  var s = switch (modifier) {
    TopLevelModifier.none => '',
    TopLevelModifier.final_ => 'final ',
    TopLevelModifier.sealed => 'sealed ',
  };
  if (mod == MemberModifier.abstract_) {
    s += 'abstract ';
  }
  return s;
}

String getTopLevelKindStr(TopLevelKind top) {
  return switch (top) {
    TopLevelKind.class_ => 'class',
    TopLevelKind.interface => 'interface',
    TopLevelKind.enum_ => 'enum',
    TopLevelKind.record => 'record',
  };
}

String getMemberModifierStr(MemberModifier mod) {
  return switch (mod) {
    MemberModifier.static_ => 'static ',
    MemberModifier.final_ => 'final ',
    MemberModifier.synchronized => 'synchronized ',
    MemberModifier.native => 'native ',
    MemberModifier.abstract_ => 'abstract ',
    MemberModifier.transient => 'transient ',
    MemberModifier.volatile => 'volatile ',
    _ => '',
  };
}

String getParamsStr(ParamCount paramCount, String typeStr) {
  return switch (paramCount) {
    ParamCount.zero => '',
    ParamCount.one => '$typeStr p1',
    ParamCount.two => '$typeStr p1, int p2',
  };
}

String getEnumConstantsStr(
    Member member, ParamCount paramCount, String typeStr) {
  if (member == Member.constructor) {
    final args = switch (paramCount) {
      ParamCount.zero => '',
      ParamCount.one => getJavaDefaultValue(typeStr),
      ParamCount.two => '${getJavaDefaultValue(typeStr)}, 0',
    };
    return '  VALUE1($args), VALUE2($args);';
  }
  return '  VALUE1, VALUE2;';
}

String getFieldStr(TopLevelKind top, MemberModifier mod, String typeStr) {
  final modStr = getMemberModifierStr(mod);
  final defaultValue = getJavaDefaultValue(typeStr);
  if (top == TopLevelKind.interface) {
    return '''
  $modStr$typeStr myField = $defaultValue;
''';
  }
  final init = mod == MemberModifier.final_ ? ' = $defaultValue' : '';
  return '''
  public $modStr$typeStr myField$init;
''';
}

String getMethodStr(TopLevelKind top, MemberModifier mod, String memberGenStr,
    String typeStr, MemberName name, String params) {
  final methodName = name == MemberName.any ? 'myMethod' : name.name;
  final defaultValue = getJavaDefaultValue(typeStr);
  final body = typeStr == 'void' ? '' : 'return $defaultValue;';
  final throwsStr = mod == MemberModifier.throws ? ' throws Exception' : '';

  if (top == TopLevelKind.interface) {
    return switch (mod) {
      MemberModifier.default_ => '''
  default $memberGenStr$typeStr $methodName($params)$throwsStr { $body }
''',
      MemberModifier.static_ => '''
  static $memberGenStr$typeStr $methodName($params)$throwsStr { $body }
''',
      _ => '''
  $memberGenStr$typeStr $methodName($params)$throwsStr;
''',
    };
  }

  final modStr = getMemberModifierStr(mod);
  return switch (mod) {
    MemberModifier.abstract_ => '''
  public abstract $memberGenStr$typeStr $methodName($params)$throwsStr;
''',
    MemberModifier.native => '''
  public native $memberGenStr$typeStr $methodName($params)$throwsStr;
''',
    _ => '''
  public $modStr$memberGenStr$typeStr $methodName($params)$throwsStr { $body }
''',
  };
}

String getConstructorStr(
    TopLevelKind top, String memberGenStr, String className, String params) {
  final visibility = top == TopLevelKind.enum_ ? 'private' : 'public';
  return '''
  $visibility $memberGenStr$className($params) {}
''';
}

String getInitializerStr(MemberModifier mod) {
  final staticStr = mod == MemberModifier.static_ ? 'static ' : '';
  return '''
  $staticStr{ }
''';
}

String getNestedStr(NestedKind nested) {
  final nKind = switch (nested) {
    NestedKind.innerClass || NestedKind.staticClass => 'class',
    NestedKind.interface => 'interface',
    NestedKind.enum_ => 'enum',
    NestedKind.record => 'record',
    _ => 'class',
  };
  if (nested == NestedKind.record) {
    return '''
  public static record NestedRecord(int x) {}
''';
  }
  if (nested == NestedKind.enum_) {
    return '''
  public enum NestedEnum { V1 }
''';
  }
  final staticStr = nested == NestedKind.innerClass ? '' : 'static ';
  return '''
  public $staticStr$nKind Nested {}
''';
}

bool isPrimitive(MemberType type) {
  return type == MemberType.int_ ||
      type == MemberType.long_ ||
      type == MemberType.short_ ||
      type == MemberType.float_ ||
      type == MemberType.double_ ||
      type == MemberType.byte_ ||
      type == MemberType.boolean_ ||
      type == MemberType.char_ ||
      type == MemberType.void_;
}

String getJavaType(MemberType kind, bool isArray, Generics generics,
    MemberGenerics mGenerics, MemberNullability mn, GenericNullability gn) {
  final useMemberScope = mGenerics != MemberGenerics.none;

  final scopeVar = useMemberScope ? 'S' : 'T';
  final scopeEnum = useMemberScope ? mGenerics : generics;

  final ggn = getGenericNullabilityStr(gn);
  final mmn = getMemberNullabilityStr(mn);

  final g = switch (scopeEnum) {
    Generics.oneParam || MemberGenerics.oneParam => '$ggn$scopeVar',
    Generics.twoParams || MemberGenerics.twoParams => '$ggn$scopeVar',
    Generics.upperBound || MemberGenerics.upperBound => '$ggn$scopeVar',
    Generics.lowerBound || MemberGenerics.lowerBound => '? super $ggn$scopeVar',
    Generics.wildcard || MemberGenerics.wildcard => '?',
    _ => '${mmn}String',
  };

  final t = switch (kind) {
    MemberType.void_ => 'void',
    MemberType.boolean_ => 'boolean',
    MemberType.char_ => 'char',
    MemberType.int_ => 'int',
    MemberType.long_ => 'long',
    MemberType.short_ => 'short',
    MemberType.float_ => 'float',
    MemberType.double_ => 'double',
    MemberType.byte_ => 'byte',
    MemberType.object => 'Object',
    MemberType.string => 'String',
    MemberType.typeParam => 'T',
    MemberType.memberTypeParam => 'S',
    MemberType.list => 'List<$g>',
    MemberType.set => 'Set<$g>',
    MemberType.map => 'Map<$g, $g>',
    MemberType.customObject => 'CustomObject<$g>',
    MemberType.customInterface => 'CustomInterface<$g>',
    MemberType.customEnum => 'CustomEnum',
    MemberType.customRecord => 'CustomRecord<$g>',
    MemberType.nestedCustom => 'NestedCustom<$g, $g>.Nested<$g>',
  };
  if (isArray) {
    if (isPrimitive(kind)) {
      return '$t $mmn[]';
    }
    return '$mmn$t[]';
  }
  return isPrimitive(kind) ? t : '$mmn$t';
}

String getJavaDefaultValue(String type) {
  if (type.endsWith('[]')) {
    return 'null';
  }
  return switch (type) {
    'void' => '',
    'int' => '0',
    'long' => '0',
    'byte' => '0',
    'short' => '0',
    'float' => '0.0f',
    'double' => '0.0',
    'boolean' => 'false',
    'char' => "' '",
    'CustomEnum' => 'CustomEnum.V1',
    _ => 'null',
  };
}
