// Copyright (c) 2015, 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.

/// A library to generate Java source code. See [JavaGenerator].
library src_gen_java;

import 'dart:io';

import 'package:path/path.dart';

import '../common/src_gen_common.dart';

/// The maximum length for javadoc comments.
int colBoundary = 100;

/// The header for every generated file.
String? fileHeader;

String classNameFor(String typeName) {
  // Convert ElementList<Foo> param declarations to List<Foo> declarations.
  if (typeName.startsWith('ElementList<')) {
    return typeName.substring('Element'.length);
  }

  var index = typeName.lastIndexOf('.');
  typeName = index > 0 ? typeName.substring(index + 1) : typeName;
  if (typeName.startsWith('_')) typeName = typeName.substring(1);
  return typeName;
}

String pkgNameFor(String typeName) {
  var index = typeName.lastIndexOf('.');
  return index > 0 ? typeName.substring(0, index) : '';
}

typedef WriteStatements = void Function(StatementWriter writer);
typedef WriteType = void Function(TypeWriter writer);

/// [JavaGenerator] generates java source files, one per Java type.
/// Typical usage:
///
///    var generator = new JavaGenerator('/path/to/java/src');
///    generator.writeType('some.package.Foo', (TypeWriter) writer) {
///      ...
///    });
///    ...
///
class JavaGenerator {
  /// The java source directory into which files are generated.
  final String srcDirPath;

  final Set<String> _generatedPaths = {};

  JavaGenerator(this.srcDirPath);

  Iterable<String> get allWrittenFiles => _generatedPaths;

  /// Generate a Java class/interface in the given package
  void writeType(String typeName, scriptLocation, WriteType write) {
    var classWriter = TypeWriter(typeName, scriptLocation);
    write(classWriter);
    var pkgDirPath = join(srcDirPath, joinAll(pkgNameFor(typeName).split('.')));
    var pkgDir = Directory(pkgDirPath);
    if (!pkgDir.existsSync()) pkgDir.createSync(recursive: true);
    var classFilePath = join(pkgDirPath, '${classNameFor(typeName)}.java');
    var classFile = File(classFilePath);
    _generatedPaths.add(classFilePath);
    classFile.writeAsStringSync(classWriter.toSource());
  }
}

class JavaMethodArg {
  final String? name;
  final String? typeName;

  JavaMethodArg(this.name, this.typeName);
}

class StatementWriter {
  final TypeWriter typeWriter;
  final StringBuffer _content = StringBuffer();

  StatementWriter(this.typeWriter);

  void addImport(String typeName) {
    typeWriter.addImport(typeName);
  }

  void addLine(String line) {
    _content.writeln('    $line');
  }

  String toSource() => _content.toString();
}

/// [TypeWriter] describes a Java type to be generated.
/// Typical usage:
///
///     writer.addImport('package.one.Bar');
///     writer.addImport('package.two.*');
///     writer.superclassName = 'package.three.Blat';
///     writer.addMethod('foo', [
///       new JavaMethodArg('arg1', 'LocalType'),
///       new JavaMethodArg('arg2', 'java.util.List'),
///     ], (StatementWriter writer) {
///       ...
///     });
///
/// The [toSource()] method generates the source,
/// but need not be called if used in conjunction with
/// [JavaGenerator].
class TypeWriter {
  final String pkgName;
  final String className;
  bool isInterface = false;
  bool isEnum = false;
  String? javadoc;
  String modifiers = 'public';
  final Set<String> _imports = <String>{};
  String? superclassName;
  List<String> interfaceNames = <String>[];
  final StringBuffer _content = StringBuffer();
  final List<String> _fields = <String>[];
  final Map<String, String> _methods = <String, String>{};
  final String scriptLocation;

  TypeWriter(String typeName, this.scriptLocation)
      : pkgName = pkgNameFor(typeName),
        className = classNameFor(typeName);

  String get kind {
    if (isInterface) return 'interface';
    if (isEnum) return 'enum';
    return 'class';
  }

  void addConstructor(Iterable<JavaMethodArg> args, WriteStatements write,
      {String? javadoc, String modifiers = 'public'}) {
    _content.writeln();
    if (javadoc != null && javadoc.isNotEmpty) {
      _content.writeln('  /**');
      wrap(javadoc.trim(), colBoundary - 6)
          .split('\n')
          .forEach((line) => _content.writeln('   * $line'));
      _content.writeln('   */');
    }
    _content.write('  $modifiers $className(');
    _content.write(
        args.map((a) => '${classNameFor(a.typeName!)} ${a.name}').join(', '));
    _content.write(')');
    _content.writeln(' {');
    StatementWriter writer = StatementWriter(this);
    write(writer);
    _content.write(writer.toSource());
    _content.writeln('  }');
  }

  void addEnumValue(
    String? name, {
    String? javadoc,
    bool isLast = false,
  }) {
    _content.writeln();
    if (javadoc != null && javadoc.isNotEmpty) {
      _content.writeln('  /**');
      wrap(javadoc.trim(), colBoundary - 6)
          .split('\n')
          .forEach((line) => _content.writeln('   * $line'));
      _content.writeln('   */');
    }
    _content.write('  $name');
    if (!isLast) {
      _content.writeln(',');
    } else {
      _content.writeln();
    }
  }

  void addField(String name, String typeName,
      {String modifiers = 'public', String? value, String? javadoc}) {
    var fieldDecl = StringBuffer();
    if (javadoc != null && javadoc.isNotEmpty) {
      fieldDecl.writeln('  /**');
      wrap(javadoc.trim(), colBoundary - 6)
          .split('\n')
          .forEach((line) => fieldDecl.writeln('   * $line'));
      fieldDecl.writeln('   */');
    }
    fieldDecl.write('  ');
    if (modifiers.isNotEmpty) {
      fieldDecl.write('$modifiers ');
    }
    fieldDecl.write('$typeName $name');
    if (value != null && value.isNotEmpty) {
      fieldDecl.write(' = $value');
    }
    fieldDecl.writeln(';');
    _fields.add(fieldDecl.toString());
  }

  void addImport(String? typeName) {
    if (typeName == null || typeName.isEmpty) return;
    var pkgName = pkgNameFor(typeName);
    if (pkgName.isNotEmpty && pkgName != this.pkgName) {
      _imports.add(typeName);
    }
  }

  void addMethod(
    String name,
    Iterable<JavaMethodArg> args,
    WriteStatements? write, {
    String? javadoc,
    String? modifiers = 'public',
    String? returnType = 'void',
    bool isOverride = false,
    bool isDeprecated = false,
  }) {
    var methodDecl = StringBuffer();
    if (javadoc != null && javadoc.isNotEmpty) {
      methodDecl.writeln('  /**');
      wrap(javadoc.trim(), colBoundary - 6)
          .split('\n')
          .forEach((line) => methodDecl.writeln('   * $line'.trimRight()));
      methodDecl.writeln('   */');
    }
    if (isDeprecated) {
      methodDecl.writeln('  @Deprecated');
    }
    if (isOverride) {
      methodDecl.writeln('  @Override');
    }
    methodDecl.write('  ');
    if (modifiers != null && modifiers.isNotEmpty) {
      if (!isInterface || modifiers != 'public') {
        methodDecl.write('$modifiers ');
      }
    }
    methodDecl.write('$returnType $name(');
    methodDecl.write(args
        .map(
            (JavaMethodArg arg) => '${classNameFor(arg.typeName!)} ${arg.name}')
        .join(', '));
    methodDecl.write(')');
    if (write != null) {
      methodDecl.writeln(' {');
      StatementWriter writer = StatementWriter(this);
      write(writer);
      methodDecl.write(writer.toSource());
      methodDecl.writeln('  }');
    } else {
      methodDecl.writeln(';');
    }
    String key = (modifiers != null && modifiers.contains('public'))
        ? '1 $name('
        : '2 $name(';
    key = args.fold(key, (String k, JavaMethodArg a) => '$k${a.typeName},');
    _methods[key] = methodDecl.toString();
  }

  String toSource() {
    var buffer = StringBuffer();
    if (fileHeader != null) buffer.write(fileHeader);
    buffer.writeln('package $pkgName;');
    buffer.writeln();
    buffer.writeln(
        '// This file is generated by the script: $scriptLocation in dart-lang/sdk.');
    buffer.writeln();
    addImport(superclassName);
    for (var t in interfaceNames) {
      addImport(t);
    }
    if (_imports.isNotEmpty) {
      var sorted = _imports.toList()..sort();
      for (String typeName in sorted) {
        buffer.writeln('import $typeName;');
      }
      buffer.writeln();
    }
    if (javadoc != null && javadoc!.isNotEmpty) {
      buffer.writeln('/**');
      wrap(javadoc!.trim(), colBoundary - 4)
          .split('\n')
          .forEach((line) => buffer.writeln(' * $line'));
      buffer.writeln(' */');
    }

    buffer.writeln('@SuppressWarnings({"WeakerAccess", "unused"})');

    buffer.write('$modifiers $kind $className');
    if (superclassName != null) {
      buffer.write(' extends ${classNameFor(superclassName!)}');
    }
    if (interfaceNames.isNotEmpty) {
      var classNames = interfaceNames.map((t) => classNameFor(t));
      buffer.write(
          ' ${isInterface ? 'extends' : 'implements'} ${classNames.join(', ')}');
    }
    buffer.writeln(' {');
    buffer.write(_content.toString());
    for (var f in _fields) {
      buffer.writeln();
      buffer.write(f);
    }
    _methods.keys.toList()
      ..sort()
      ..forEach((String methodName) {
        buffer.writeln();
        buffer.write(_methods[methodName]);
      });
    buffer.writeln('}');
    return buffer.toString();
  }
}
