// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'ast.dart';
import 'functional.dart';
import 'generator_tools.dart';
import 'pigeon_lib.dart' show TaskQueueType;

/// Documentation open symbol.
const String _docCommentPrefix = '/**';

/// Documentation continuation symbol.
const String _docCommentContinuation = ' *';

/// Documentation close symbol.
const String _docCommentSuffix = ' */';

/// Documentation comment spec.
const DocumentCommentSpecification _docCommentSpec =
    DocumentCommentSpecification(
  _docCommentPrefix,
  closeCommentToken: _docCommentSuffix,
  blockContinuationToken: _docCommentContinuation,
);

/// Options that control how Kotlin code will be generated.
class KotlinOptions {
  /// Creates a [KotlinOptions] object
  const KotlinOptions({
    this.package,
    this.copyrightHeader,
  });

  /// The package where the generated class will live.
  final String? package;

  /// A copyright header that will get prepended to generated code.
  final Iterable<String>? copyrightHeader;

  /// Creates a [KotlinOptions] from a Map representation where:
  /// `x = KotlinOptions.fromMap(x.toMap())`.
  static KotlinOptions fromMap(Map<String, Object> map) {
    return KotlinOptions(
      package: map['package'] as String?,
      copyrightHeader: map['copyrightHeader'] as Iterable<String>?,
    );
  }

  /// Converts a [KotlinOptions] to a Map representation where:
  /// `x = KotlinOptions.fromMap(x.toMap())`.
  Map<String, Object> toMap() {
    final Map<String, Object> result = <String, Object>{
      if (package != null) 'package': package!,
      if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!,
    };
    return result;
  }

  /// Overrides any non-null parameters from [options] into this to make a new
  /// [KotlinOptions].
  KotlinOptions merge(KotlinOptions options) {
    return KotlinOptions.fromMap(mergeMaps(toMap(), options.toMap()));
  }
}

/// Calculates the name of the codec that will be generated for [api].
String _getCodecName(Api api) => '${api.name}Codec';

/// Writes the codec class that will be used by [api].
/// Example:
/// private static class FooCodec extends StandardMessageCodec {...}
void _writeCodec(Indent indent, Api api, Root root) {
  assert(getCodecClasses(api, root).isNotEmpty);
  final Iterable<EnumeratedClass> codecClasses = getCodecClasses(api, root);
  final String codecName = _getCodecName(api);
  indent.writeln('@Suppress("UNCHECKED_CAST")');
  indent.write('private object $codecName : StandardMessageCodec() ');
  indent.scoped('{', '}', () {
    indent.write(
        'override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? ');
    indent.scoped('{', '}', () {
      indent.write('return when (type) ');
      indent.scoped('{', '}', () {
        for (final EnumeratedClass customClass in codecClasses) {
          indent.write('${customClass.enumeration}.toByte() -> ');
          indent.scoped('{', '}', () {
            indent.write(
                'return (readValue(buffer) as? Map<String, Any?>)?.let ');
            indent.scoped('{', '}', () {
              indent.writeln('${customClass.name}.fromMap(it)');
            });
          });
        }
        indent.writeln('else -> super.readValueOfType(type, buffer)');
      });
    });

    indent.write(
        'override fun writeValue(stream: ByteArrayOutputStream, value: Any?) ');
    indent.writeScoped('{', '}', () {
      indent.write('when (value) ');
      indent.scoped('{', '}', () {
        for (final EnumeratedClass customClass in codecClasses) {
          indent.write('is ${customClass.name} -> ');
          indent.scoped('{', '}', () {
            indent.writeln('stream.write(${customClass.enumeration})');
            indent.writeln('writeValue(stream, value.toMap())');
          });
        }
        indent.writeln('else -> super.writeValue(stream, value)');
      });
    });
  });
}

/// Write the kotlin code that represents a host [Api], [api].
/// Example:
/// interface Foo {
///   Int add(x: Int, y: Int);
///   companion object {
///     fun setUp(binaryMessenger: BinaryMessenger, api: Api) {...}
///   }
/// }
void _writeHostApi(Indent indent, Api api, Root root) {
  assert(api.location == ApiLocation.host);

  final String apiName = api.name;

  final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty;

  const List<String> generatedMessages = <String>[
    ' Generated interface from Pigeon that represents a handler of messages from Flutter.'
  ];
  addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
      generatorComments: generatedMessages);

  indent.write('interface $apiName ');
  indent.scoped('{', '}', () {
    for (final Method method in api.methods) {
      final List<String> argSignature = <String>[];
      if (method.arguments.isNotEmpty) {
        final Iterable<String> argTypes = method.arguments
            .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type));
        final Iterable<String> argNames =
            method.arguments.map((NamedType e) => e.name);
        argSignature
            .addAll(map2(argTypes, argNames, (String argType, String argName) {
          return '$argName: $argType';
        }));
      }

      final String returnType = method.returnType.isVoid
          ? ''
          : _nullsafeKotlinTypeForDartType(method.returnType);

      addDocumentationComments(
          indent, method.documentationComments, _docCommentSpec);

      if (method.isAsynchronous) {
        argSignature.add('callback: ($returnType) -> Unit');
        indent.writeln('fun ${method.name}(${argSignature.join(', ')})');
      } else if (method.returnType.isVoid) {
        indent.writeln('fun ${method.name}(${argSignature.join(', ')})');
      } else {
        indent.writeln(
            'fun ${method.name}(${argSignature.join(', ')}): $returnType');
      }
    }

    indent.addln('');
    indent.write('companion object ');
    indent.scoped('{', '}', () {
      indent.writeln('/** The codec used by $apiName. */');
      indent.write('val codec: MessageCodec<Any?> by lazy ');
      indent.scoped('{', '}', () {
        if (isCustomCodec) {
          indent.writeln(_getCodecName(api));
        } else {
          indent.writeln('StandardMessageCodec()');
        }
      });
      indent.writeln(
          '/** Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`. */');
      indent.writeln('@Suppress("UNCHECKED_CAST")');
      indent.write(
          'fun setUp(binaryMessenger: BinaryMessenger, api: $apiName?) ');
      indent.scoped('{', '}', () {
        for (final Method method in api.methods) {
          indent.write('run ');
          indent.scoped('{', '}', () {
            String? taskQueue;
            if (method.taskQueueType != TaskQueueType.serial) {
              taskQueue = 'taskQueue';
              indent.writeln(
                  'val $taskQueue = binaryMessenger.makeBackgroundTaskQueue()');
            }

            final String channelName = makeChannelName(api, method);

            indent.write(
                'val channel = BasicMessageChannel<Any?>(binaryMessenger, "$channelName", codec');

            if (taskQueue != null) {
              indent.addln(', $taskQueue)');
            } else {
              indent.addln(')');
            }

            indent.write('if (api != null) ');
            indent.scoped('{', '}', () {
              final String messageVarName =
                  method.arguments.isNotEmpty ? 'message' : '_';

              indent.write('channel.setMessageHandler ');
              indent.scoped('{ $messageVarName, reply ->', '}', () {
                indent.writeln('val wrapped = hashMapOf<String, Any?>()');

                indent.write('try ');
                indent.scoped('{', '}', () {
                  final List<String> methodArgument = <String>[];
                  if (method.arguments.isNotEmpty) {
                    indent.writeln('val args = message as List<Any?>');
                    enumerate(method.arguments, (int index, NamedType arg) {
                      final String argName = _getSafeArgumentName(index, arg);
                      final String argIndex = 'args[$index]';
                      indent.writeln(
                          'val $argName = ${_castForceUnwrap(argIndex, arg.type, root)}');
                      methodArgument.add(argName);
                    });
                  }
                  final String call =
                      'api.${method.name}(${methodArgument.join(', ')})';
                  if (method.isAsynchronous) {
                    indent.write('$call ');
                    if (method.returnType.isVoid) {
                      indent.scoped('{', '}', () {
                        indent.writeln('reply.reply(null)');
                      });
                    } else {
                      indent.scoped('{', '}', () {
                        indent.writeln('reply.reply(wrapResult(it))');
                      });
                    }
                  } else if (method.returnType.isVoid) {
                    indent.writeln(call);
                    indent.writeln('wrapped["${Keys.result}"] = null');
                  } else {
                    indent.writeln('wrapped["${Keys.result}"] = $call');
                  }
                }, addTrailingNewline: false);
                indent.add(' catch (exception: Error) ');
                indent.scoped('{', '', () {
                  indent.writeln(
                      'wrapped["${Keys.error}"] = wrapError(exception)');
                  if (method.isAsynchronous) {
                    indent.writeln('reply.reply(wrapped)');
                  }
                });
                if (!method.isAsynchronous) {
                  indent.writeln('reply.reply(wrapped)');
                }
              });
            }, addTrailingNewline: false);
            indent.scoped('} else {', '}', () {
              indent.writeln('channel.setMessageHandler(null)');
            });
          });
        }
      });
    });
  });
}

String _getArgumentName(int count, NamedType argument) =>
    argument.name.isEmpty ? 'arg$count' : argument.name;

/// Returns an argument name that can be used in a context where it is possible to collide.
String _getSafeArgumentName(int count, NamedType argument) =>
    '${_getArgumentName(count, argument)}Arg';

/// Writes the code for a flutter [Api], [api].
/// Example:
/// class Foo(private val binaryMessenger: BinaryMessenger) {
///   fun add(x: Int, y: Int, callback: (Int?) -> Unit) {...}
/// }
void _writeFlutterApi(Indent indent, Api api, Root root) {
  assert(api.location == ApiLocation.flutter);
  final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty;

  const List<String> generatedMessages = <String>[
    ' Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.'
  ];
  addDocumentationComments(indent, api.documentationComments, _docCommentSpec,
      generatorComments: generatedMessages);

  final String apiName = api.name;
  indent.writeln('@Suppress("UNCHECKED_CAST")');
  indent.write('class $apiName(private val binaryMessenger: BinaryMessenger) ');
  indent.scoped('{', '}', () {
    indent.write('companion object ');
    indent.scoped('{', '}', () {
      indent.writeln('/** The codec used by $apiName. */');
      indent.write('val codec: MessageCodec<Any?> by lazy ');
      indent.scoped('{', '}', () {
        if (isCustomCodec) {
          indent.writeln(_getCodecName(api));
        } else {
          indent.writeln('StandardMessageCodec()');
        }
      });
    });

    for (final Method func in api.methods) {
      final String channelName = makeChannelName(api, func);
      final String returnType = func.returnType.isVoid
          ? ''
          : _nullsafeKotlinTypeForDartType(func.returnType);
      String sendArgument;

      addDocumentationComments(
          indent, func.documentationComments, _docCommentSpec);

      if (func.arguments.isEmpty) {
        indent.write('fun ${func.name}(callback: ($returnType) -> Unit) ');
        sendArgument = 'null';
      } else {
        final Iterable<String> argTypes = func.arguments
            .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type));
        final Iterable<String> argNames =
            indexMap(func.arguments, _getSafeArgumentName);
        sendArgument = 'listOf(${argNames.join(', ')})';
        final String argsSignature = map2(argTypes, argNames,
            (String type, String name) => '$name: $type').join(', ');
        if (func.returnType.isVoid) {
          indent
              .write('fun ${func.name}($argsSignature, callback: () -> Unit) ');
        } else {
          indent.write(
              'fun ${func.name}($argsSignature, callback: ($returnType) -> Unit) ');
        }
      }
      indent.scoped('{', '}', () {
        const String channel = 'channel';
        indent.writeln(
            'val $channel = BasicMessageChannel<Any?>(binaryMessenger, "$channelName", codec)');
        indent.write('$channel.send($sendArgument) ');
        if (func.returnType.isVoid) {
          indent.scoped('{', '}', () {
            indent.writeln('callback()');
          });
        } else {
          final String forceUnwrap = func.returnType.isNullable ? '?' : '';
          indent.scoped('{', '}', () {
            indent.writeln('val result = it as$forceUnwrap $returnType');
            indent.writeln('callback(result)');
          });
        }
      });
    }
  });
}

String _castForceUnwrap(String value, TypeDeclaration type, Root root) {
  if (isEnum(root, type)) {
    final String forceUnwrap = type.isNullable ? '' : '!!';
    final String nullableConditionPrefix =
        type.isNullable ? '$value == null ? null : ' : '';
    return '$nullableConditionPrefix${_kotlinTypeForDartType(type)}.ofRaw($value as Int)$forceUnwrap';
  } else {
    final String castUnwrap = type.isNullable ? '?' : '';

    // The StandardMessageCodec can give us [Integer, Long] for
    // a Dart 'int'.  To keep things simple we just use 64bit
    // longs in Pigeon with Kotlin.
    if (type.baseName == 'int') {
      return '$value.let { if (it is Int) it.toLong() else it as$castUnwrap Long }';
    } else {
      return '$value as$castUnwrap ${_kotlinTypeForDartType(type)}';
    }
  }
}

/// Converts a [List] of [TypeDeclaration]s to a comma separated [String] to be
/// used in Kotlin code.
String _flattenTypeArguments(List<TypeDeclaration> args) {
  return args.map(_kotlinTypeForDartType).join(', ');
}

String _kotlinTypeForBuiltinGenericDartType(TypeDeclaration type) {
  if (type.typeArguments.isEmpty) {
    switch (type.baseName) {
      case 'List':
        return 'List<Any?>';
      case 'Map':
        return 'Map<Any, Any?>';
      default:
        return 'Any';
    }
  } else {
    switch (type.baseName) {
      case 'List':
        return 'List<${_nullsafeKotlinTypeForDartType(type.typeArguments.first)}>';
      case 'Map':
        return 'Map<${_nullsafeKotlinTypeForDartType(type.typeArguments.first)}, ${_nullsafeKotlinTypeForDartType(type.typeArguments.last)}>';
      default:
        return '${type.baseName}<${_flattenTypeArguments(type.typeArguments)}>';
    }
  }
}

String? _kotlinTypeForBuiltinDartType(TypeDeclaration type) {
  const Map<String, String> kotlinTypeForDartTypeMap = <String, String>{
    'void': 'Void',
    'bool': 'Boolean',
    'String': 'String',
    'int': 'Long',
    'double': 'Double',
    'Uint8List': 'ByteArray',
    'Int32List': 'IntArray',
    'Int64List': 'LongArray',
    'Float32List': 'FloatArray',
    'Float64List': 'DoubleArray',
    'Object': 'Any',
  };
  if (kotlinTypeForDartTypeMap.containsKey(type.baseName)) {
    return kotlinTypeForDartTypeMap[type.baseName];
  } else if (type.baseName == 'List' || type.baseName == 'Map') {
    return _kotlinTypeForBuiltinGenericDartType(type);
  } else {
    return null;
  }
}

String _kotlinTypeForDartType(TypeDeclaration type) {
  return _kotlinTypeForBuiltinDartType(type) ?? type.baseName;
}

String _nullsafeKotlinTypeForDartType(TypeDeclaration type) {
  final String nullSafe = type.isNullable ? '?' : '';
  return '${_kotlinTypeForDartType(type)}$nullSafe';
}

/// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the
/// provided [options].
void generateKotlin(KotlinOptions options, Root root, StringSink sink) {
  final Set<String> rootClassNameSet =
      root.classes.map((Class x) => x.name).toSet();
  final Set<String> rootEnumNameSet =
      root.enums.map((Enum x) => x.name).toSet();
  final Indent indent = Indent(sink);

  HostDatatype getHostDatatype(NamedType field) {
    return getFieldHostDatatype(field, root.classes, root.enums,
        (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x));
  }

  void writeHeader() {
    if (options.copyrightHeader != null) {
      addLines(indent, options.copyrightHeader!, linePrefix: '// ');
    }
    indent.writeln('// $generatedCodeWarning');
    indent.writeln('// $seeAlsoWarning');
  }

  void writeImports() {
    indent.writeln('import android.util.Log');
    indent.writeln('import io.flutter.plugin.common.BasicMessageChannel');
    indent.writeln('import io.flutter.plugin.common.BinaryMessenger');
    indent.writeln('import io.flutter.plugin.common.MessageCodec');
    indent.writeln('import io.flutter.plugin.common.StandardMessageCodec');
    indent.writeln('import java.io.ByteArrayOutputStream');
    indent.writeln('import java.nio.ByteBuffer');
  }

  void writeEnum(Enum anEnum) {
    addDocumentationComments(
        indent, anEnum.documentationComments, _docCommentSpec);
    indent.write('enum class ${anEnum.name}(val raw: Int) ');
    indent.scoped('{', '}', () {
      // We use explicit indexing here as use of the ordinal() method is
      // discouraged. The toMap and fromMap API matches class API to allow
      // the same code to work with enums and classes, but this
      // can also be done directly in the host and flutter APIs.
      int index = 0;
      for (final String member in anEnum.members) {
        indent.write('${member.toUpperCase()}($index)');
        if (index != anEnum.members.length - 1) {
          indent.addln(',');
        } else {
          indent.addln(';');
        }
        index++;
      }

      indent.writeln('');
      indent.write('companion object ');
      indent.scoped('{', '}', () {
        indent.write('fun ofRaw(raw: Int): ${anEnum.name}? ');
        indent.scoped('{', '}', () {
          indent.writeln('return values().firstOrNull { it.raw == raw }');
        });
      });
    });
  }

  void writeDataClass(Class klass) {
    void writeField(NamedType field) {
      addDocumentationComments(
          indent, field.documentationComments, _docCommentSpec);
      indent.write(
          'val ${field.name}: ${_nullsafeKotlinTypeForDartType(field.type)}');
      final String defaultNil = field.type.isNullable ? ' = null' : '';
      indent.add(defaultNil);
    }

    void writeToMap() {
      indent.write('fun toMap(): Map<String, Any?> ');
      indent.scoped('{', '}', () {
        indent.writeln('val map = mutableMapOf<String, Any?>()');

        for (final NamedType field in klass.fields) {
          final HostDatatype hostDatatype = getHostDatatype(field);
          String toWriteValue = '';
          final String fieldName = field.name;
          final String prefix = field.type.isNullable ? 'it' : fieldName;
          if (!hostDatatype.isBuiltin &&
              rootClassNameSet.contains(field.type.baseName)) {
            toWriteValue = '$prefix.toMap()';
          } else if (!hostDatatype.isBuiltin &&
              rootEnumNameSet.contains(field.type.baseName)) {
            toWriteValue = '$prefix.raw';
          } else {
            toWriteValue = prefix;
          }

          if (field.type.isNullable) {
            indent.writeln(
                '$fieldName?.let { map["${field.name}"] = $toWriteValue }');
          } else {
            indent.writeln('map["${field.name}"] = $toWriteValue');
          }
        }

        indent.writeln('return map');
      });
    }

    void writeFromMap() {
      final String className = klass.name;

      indent.write('companion object ');
      indent.scoped('{', '}', () {
        indent.writeln('@Suppress("UNCHECKED_CAST")');
        indent.write('fun fromMap(map: Map<String, Any?>): $className ');

        indent.scoped('{', '}', () {
          for (final NamedType field in klass.fields) {
            final HostDatatype hostDatatype = getHostDatatype(field);

            // The StandardMessageCodec can give us [Integer, Long] for
            // a Dart 'int'.  To keep things simple we just use 64bit
            // longs in Pigeon with Kotlin.
            final bool isInt = field.type.baseName == 'int';

            final String mapValue = 'map["${field.name}"]';
            final String fieldType = _kotlinTypeForDartType(field.type);

            if (field.type.isNullable) {
              if (!hostDatatype.isBuiltin &&
                  rootClassNameSet.contains(field.type.baseName)) {
                indent.write('val ${field.name}: $fieldType? = ');
                indent.add('($mapValue as? Map<String, Any?>)?.let ');
                indent.scoped('{', '}', () {
                  indent.writeln('$fieldType.fromMap(it)');
                });
              } else if (!hostDatatype.isBuiltin &&
                  rootEnumNameSet.contains(field.type.baseName)) {
                indent.write('val ${field.name}: $fieldType? = ');
                indent.add('($mapValue as? Int)?.let ');
                indent.scoped('{', '}', () {
                  indent.writeln('$fieldType.ofRaw(it)');
                });
              } else if (isInt) {
                indent.write('val ${field.name} = $mapValue');
                indent.addln(
                    '.let { if (it is Int) it.toLong() else it as? Long }');
              } else {
                indent.writeln('val ${field.name} = $mapValue as? $fieldType');
              }
            } else {
              if (!hostDatatype.isBuiltin &&
                  rootClassNameSet.contains(field.type.baseName)) {
                indent.writeln(
                    'val ${field.name} = $fieldType.fromMap($mapValue as Map<String, Any?>)');
              } else if (!hostDatatype.isBuiltin &&
                  rootEnumNameSet.contains(field.type.baseName)) {
                indent.write(
                    'val ${field.name} = $fieldType.ofRaw($mapValue as Int)!!');
              } else {
                indent.writeln('val ${field.name} = $mapValue as $fieldType');
              }
            }
          }

          indent.writeln('');
          indent.write('return $className(');
          for (final NamedType field in klass.fields) {
            final String comma = klass.fields.last == field ? '' : ', ';
            indent.add('${field.name}$comma');
          }
          indent.addln(')');
        });
      });
    }

    const List<String> generatedMessages = <String>[
      ' Generated class from Pigeon that represents data sent in messages.'
    ];
    addDocumentationComments(
        indent, klass.documentationComments, _docCommentSpec,
        generatorComments: generatedMessages);

    indent.write('data class ${klass.name} ');
    indent.scoped('(', '', () {
      for (final NamedType element in klass.fields) {
        writeField(element);
        if (klass.fields.last != element) {
          indent.addln(',');
        } else {
          indent.addln('');
        }
      }
    });

    indent.scoped(') {', '}', () {
      writeFromMap();
      writeToMap();
    });
  }

  void writeApi(Api api) {
    if (api.location == ApiLocation.host) {
      _writeHostApi(indent, api, root);
    } else if (api.location == ApiLocation.flutter) {
      _writeFlutterApi(indent, api, root);
    }
  }

  void writeWrapResult() {
    indent.write('private fun wrapResult(result: Any?): Map<String, Any?> ');
    indent.scoped('{', '}', () {
      indent.writeln('return hashMapOf("result" to result)');
    });
  }

  void writeWrapError() {
    indent.write(
        'private fun wrapError(exception: Throwable): Map<String, Any> ');
    indent.scoped('{', '}', () {
      indent.write('return ');
      indent.scoped('hashMapOf<String, Any>(', ')', () {
        indent.write('"error" to ');
        indent.scoped('hashMapOf<String, Any>(', ')', () {
          indent.writeln(
              '"${Keys.errorCode}" to exception.javaClass.simpleName,');
          indent.writeln('"${Keys.errorMessage}" to exception.toString(),');
          indent.writeln(
              '"${Keys.errorDetails}" to "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)');
        });
      });
    });
  }

  writeHeader();
  indent.addln('');
  if (options.package != null) {
    indent.writeln('package ${options.package}');
  }
  indent.addln('');
  writeImports();
  indent.addln('');
  indent.writeln('/** Generated class from Pigeon. */');
  for (final Enum anEnum in root.enums) {
    indent.writeln('');
    writeEnum(anEnum);
  }

  for (final Class klass in root.classes) {
    indent.addln('');
    writeDataClass(klass);
  }

  if (root.apis.any((Api api) =>
      api.location == ApiLocation.host &&
      api.methods.any((Method it) => it.isAsynchronous))) {
    indent.addln('');
  }

  for (final Api api in root.apis) {
    if (getCodecClasses(api, root).isNotEmpty) {
      _writeCodec(indent, api, root);
      indent.addln('');
    }
    writeApi(api);
  }

  indent.addln('');
  writeWrapResult();
  indent.addln('');
  writeWrapError();
}
