// 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';

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

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

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

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

  /// Overrides any non-null parameters from [options] into this to make a new
  /// [SwiftOptions].
  SwiftOptions merge(SwiftOptions options) {
    return SwiftOptions.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 classwill be used for encoding messages for the [api].
/// Example:
/// private class FooHostApiCodecReader: FlutterStandardReader {...}
/// private class FooHostApiCodecWriter: FlutterStandardWriter {...}
/// private class FooHostApiCodecReaderWriter: FlutterStandardReaderWriter {...}
void _writeCodec(Indent indent, Api api, Root root) {
  final String codecName = _getCodecName(api);
  final String readerWriterName = '${codecName}ReaderWriter';
  final String readerName = '${codecName}Reader';
  final String writerName = '${codecName}Writer';

  // Generate Reader
  indent.write('private class $readerName: FlutterStandardReader ');
  indent.scoped('{', '}', () {
    if (getCodecClasses(api, root).isNotEmpty) {
      indent.write('override func readValue(ofType type: UInt8) -> Any? ');
      indent.scoped('{', '}', () {
        indent.write('switch type ');
        indent.scoped('{', '}', () {
          for (final EnumeratedClass customClass
              in getCodecClasses(api, root)) {
            indent.write('case ${customClass.enumeration}:');
            indent.scoped('', '', () {
              indent.write(
                  'return ${customClass.name}.fromMap(self.readValue() as! [String: Any])');
            });
          }
          indent.write('default:');
          indent.scoped('', '', () {
            indent.writeln('return super.readValue(ofType: type)');
          });
        });
      });
    }
  });

  // Generate Writer
  indent.write('private class $writerName: FlutterStandardWriter ');
  indent.scoped('{', '}', () {
    if (getCodecClasses(api, root).isNotEmpty) {
      indent.write('override func writeValue(_ value: Any) ');
      indent.scoped('{', '}', () {
        indent.write('');
        for (final EnumeratedClass customClass in getCodecClasses(api, root)) {
          indent.add('if let value = value as? ${customClass.name} ');
          indent.scoped('{', '} else ', () {
            indent.writeln('super.writeByte(${customClass.enumeration})');
            indent.writeln('super.writeValue(value.toMap())');
          }, addTrailingNewline: false);
        }
        indent.scoped('{', '}', () {
          indent.writeln('super.writeValue(value)');
        });
      });
    }
  });
  indent.writeln('');

  // Generate ReaderWriter
  indent.write('private class $readerWriterName: FlutterStandardReaderWriter ');
  indent.scoped('{', '}', () {
    indent.write(
        'override func reader(with data: Data) -> FlutterStandardReader ');
    indent.scoped('{', '}', () {
      indent.writeln('return $readerName(data: data)');
    });
    indent.writeln('');
    indent.write(
        'override func writer(with data: NSMutableData) -> FlutterStandardWriter ');
    indent.scoped('{', '}', () {
      indent.writeln('return $writerName(data: data)');
    });
  });
  indent.writeln('');

  // Generate Codec
  indent.write('class $codecName: FlutterStandardMessageCodec ');
  indent.scoped('{', '}', () {
    indent.writeln(
        'static let shared = $codecName(readerWriter: $readerWriterName())');
  });
}

/// Write the swift code that represents a host [Api], [api].
/// Example:
/// protocol Foo {
///   Int32 add(x: Int32, y: Int32)
/// }
void _writeHostApi(Indent indent, Api api, Root root) {
  assert(api.location == ApiLocation.host);

  final String apiName = api.name;

  indent.writeln(
      '/// Generated protocol from Pigeon that represents a handler of messages from Flutter.');
  indent.write('protocol $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) => _nullsafeSwiftTypeForDartType(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
          ? ''
          : _nullsafeSwiftTypeForDartType(method.returnType);
      if (method.isAsynchronous) {
        argSignature.add('completion: @escaping ($returnType) -> Void');
        indent.writeln('func ${method.name}(${argSignature.join(', ')})');
      } else if (method.returnType.isVoid) {
        indent.writeln('func ${method.name}(${argSignature.join(', ')})');
      } else {
        indent.writeln(
            'func ${method.name}(${argSignature.join(', ')}) -> $returnType');
      }
    }
  });

  indent.addln('');
  indent.writeln(
      '/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.');
  indent.write('class ${apiName}Setup ');
  indent.scoped('{', '}', () {
    final String codecName = _getCodecName(api);
    indent.writeln('/// The codec used by $apiName.');
    indent.writeln(
        'static var codec: FlutterStandardMessageCodec { $codecName.shared }');
    indent.writeln(
        '/// Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`.');
    indent.write(
        'static func setUp(binaryMessenger: FlutterBinaryMessenger, api: $apiName?) ');
    indent.scoped('{', '}', () {
      for (final Method method in api.methods) {
        final String channelName = makeChannelName(api, method);
        final String varChannelName = '${method.name}Channel';

        indent.writeln(
            'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger, codec: codec)');
        indent.write('if let api = api ');
        indent.scoped('{', '}', () {
          indent.write('$varChannelName.setMessageHandler ');
          final String messageVarName =
              method.arguments.isNotEmpty ? 'message' : '_';
          indent.scoped('{ $messageVarName, reply in', '}', () {
            final List<String> methodArgument = <String>[];
            if (method.arguments.isNotEmpty) {
              indent.writeln('let args = message as! [Any?]');
              enumerate(method.arguments, (int index, NamedType arg) {
                final String argName = _getSafeArgumentName(index, arg);
                final String argIndex = 'args[$index]';
                indent.writeln(
                    'let $argName = ${_castForceUnwrap(argIndex, arg.type, root)}');
                methodArgument.add('${arg.name}: $argName');
              });
            }
            final String call =
                'api.${method.name}(${methodArgument.join(', ')})';
            if (method.isAsynchronous) {
              indent.write('$call ');
              if (method.returnType.isVoid) {
                indent.scoped('{', '}', () {
                  indent.writeln('reply(nil)');
                });
              } else {
                indent.scoped('{ result in', '}', () {
                  indent.writeln('reply(wrapResult(result))');
                });
              }
            } else {
              if (method.returnType.isVoid) {
                indent.writeln(call);
                indent.writeln('reply(nil)');
              } else {
                indent.writeln('let result = $call');
                indent.writeln('reply(wrapResult(result))');
              }
            }
          });
        }, addTrailingNewline: false);
        indent.scoped(' else {', '}', () {
          indent.writeln('$varChannelName.setMessageHandler(nil)');
        });
      }
    });
  });
}

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';

String _camelCase(String text) {
  final String pascal = text.split('_').map((String part) {
    return part.isEmpty ? '' : part[0].toUpperCase() + part.substring(1);
  }).join();
  return pascal[0].toLowerCase() + pascal.substring(1);
}

/// Writes the code for a flutter [Api], [api].
/// Example:
/// class Foo {
///   private let binaryMessenger: FlutterBinaryMessenger
///   init(binaryMessenger: FlutterBinaryMessenger) {...}
///   func add(x: Int32, y: Int32, completion: @escaping (Int32?) -> Void) {...}
/// }
void _writeFlutterApi(Indent indent, Api api, Root root) {
  assert(api.location == ApiLocation.flutter);
  indent.writeln(
      '/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.');
  indent.write('class ${api.name} ');
  indent.scoped('{', '}', () {
    indent.writeln('private let binaryMessenger: FlutterBinaryMessenger');
    indent.write('init(binaryMessenger: FlutterBinaryMessenger)');
    indent.scoped('{', '}', () {
      indent.writeln('self.binaryMessenger = binaryMessenger');
    });
    final String codecName = _getCodecName(api);
    indent.write('var codec: FlutterStandardMessageCodec ');
    indent.scoped('{', '}', () {
      indent.writeln('return $codecName.shared');
    });
    for (final Method func in api.methods) {
      final String channelName = makeChannelName(api, func);
      final String returnType = func.returnType.isVoid
          ? ''
          : _nullsafeSwiftTypeForDartType(func.returnType);
      String sendArgument;
      if (func.arguments.isEmpty) {
        indent.write(
            'func ${func.name}(completion: @escaping ($returnType) -> Void) ');
        sendArgument = 'nil';
      } else {
        final Iterable<String> argTypes = func.arguments
            .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type));
        final Iterable<String> argLabels =
            indexMap(func.arguments, _getArgumentName);
        final Iterable<String> argNames =
            indexMap(func.arguments, _getSafeArgumentName);
        sendArgument = '[${argNames.join(', ')}]';
        final String argsSignature = map3(
            argTypes,
            argLabels,
            argNames,
            (String type, String label, String name) =>
                '$label $name: $type').join(', ');
        if (func.returnType.isVoid) {
          indent.write(
              'func ${func.name}($argsSignature, completion: @escaping () -> Void) ');
        } else {
          indent.write(
              'func ${func.name}($argsSignature, completion: @escaping ($returnType) -> Void) ');
        }
      }
      indent.scoped('{', '}', () {
        const String channel = 'channel';
        indent.writeln(
            'let $channel = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger, codec: codec)');
        indent.write('$channel.sendMessage($sendArgument) ');
        if (func.returnType.isVoid) {
          indent.scoped('{ _ in', '}', () {
            indent.writeln('completion()');
          });
        } else {
          indent.scoped('{ response in', '}', () {
            indent.writeln(
                'let result = ${_castForceUnwrap("response", func.returnType, root)}');
            indent.writeln('completion(result)');
          });
        }
      });
    }
  });
}

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

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

String _swiftTypeForBuiltinGenericDartType(TypeDeclaration type) {
  if (type.typeArguments.isEmpty) {
    if (type.baseName == 'List') {
      return '[Any?]';
    } else if (type.baseName == 'Map') {
      return '[AnyHashable: Any?]';
    } else {
      return 'Any';
    }
  } else {
    if (type.baseName == 'List') {
      return '[${_nullsafeSwiftTypeForDartType(type.typeArguments.first)}]';
    } else if (type.baseName == 'Map') {
      return '[${_nullsafeSwiftTypeForDartType(type.typeArguments.first)}: ${_nullsafeSwiftTypeForDartType(type.typeArguments.last)}]';
    } else {
      return '${type.baseName}<${_flattenTypeArguments(type.typeArguments)}>';
    }
  }
}

String? _swiftTypeForBuiltinDartType(TypeDeclaration type) {
  const Map<String, String> swiftTypeForDartTypeMap = <String, String>{
    'void': 'Void',
    'bool': 'Bool',
    'String': 'String',
    'int': 'Int32',
    'double': 'Double',
    'Uint8List': '[UInt8]',
    'Int32List': '[Int32]',
    'Int64List': '[Int64]',
    'Float32List': '[Float32]',
    'Float64List': '[Float64]',
    'Object': 'Any',
  };
  if (swiftTypeForDartTypeMap.containsKey(type.baseName)) {
    return swiftTypeForDartTypeMap[type.baseName];
  } else if (type.baseName == 'List' || type.baseName == 'Map') {
    return _swiftTypeForBuiltinGenericDartType(type);
  } else {
    return null;
  }
}

String _swiftTypeForDartType(TypeDeclaration type) {
  return _swiftTypeForBuiltinDartType(type) ?? type.baseName;
}

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

/// Generates the ".swift" file for the AST represented by [root] to [sink] with the
/// provided [options].
void generateSwift(SwiftOptions 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) => _swiftTypeForBuiltinDartType(x));
  }

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

  void writeImports() {
    indent.writeln('import Foundation');
    indent.writeln('import Flutter');
  }

  void writeEnum(Enum anEnum) {
    indent.write('enum ${anEnum.name}: 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.writeln('case ${_camelCase(member)} = $index');
        index++;
      }
    });
  }

  void writeDataClass(Class klass) {
    void writeField(NamedType field) {
      indent.write(
          'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}');
      final String defaultNil = field.type.isNullable ? ' = nil' : '';
      indent.addln(defaultNil);
    }

    void writeToMap() {
      indent.write('func toMap() -> [String: Any?] ');
      indent.scoped('{', '}', () {
        indent.write('return ');
        indent.scoped('[', ']', () {
          for (final NamedType field in klass.fields) {
            final HostDatatype hostDatatype = getHostDatatype(field);
            String toWriteValue = '';
            final String fieldName = field.name;
            final String nullsafe = field.type.isNullable ? '?' : '';
            if (!hostDatatype.isBuiltin &&
                rootClassNameSet.contains(field.type.baseName)) {
              toWriteValue = '$fieldName$nullsafe.toMap()';
            } else if (!hostDatatype.isBuiltin &&
                rootEnumNameSet.contains(field.type.baseName)) {
              toWriteValue = '$fieldName$nullsafe.rawValue';
            } else {
              toWriteValue = field.name;
            }

            final String comma = klass.fields.last == field ? '' : ',';

            indent.writeln('"${field.name}": $toWriteValue$comma');
          }
        });
      });
    }

    void writeFromMap() {
      final String className = klass.name;
      indent
          .write('static func fromMap(_ map: [String: Any?]) -> $className? ');

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

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

          if (field.type.isNullable) {
            if (!hostDatatype.isBuiltin &&
                rootClassNameSet.contains(field.type.baseName)) {
              indent.writeln('var ${field.name}: $fieldType? = nil');
              indent.write(
                  'if let ${field.name}Map = $mapValue as? [String: Any?] ');
              indent.scoped('{', '}', () {
                indent.writeln(
                    '${field.name} = $fieldType.fromMap(${field.name}Map)');
              });
            } else if (!hostDatatype.isBuiltin &&
                rootEnumNameSet.contains(field.type.baseName)) {
              indent.writeln('var ${field.name}: $fieldType? = nil');
              indent.write('if let ${field.name}RawValue = $mapValue as? Int ');
              indent.scoped('{', '}', () {
                indent.writeln(
                    '${field.name} = $fieldType(rawValue: ${field.name}RawValue)');
              });
            } else {
              indent.writeln('let ${field.name} = $mapValue as? $fieldType ');
            }
          } else {
            if (!hostDatatype.isBuiltin &&
                rootClassNameSet.contains(field.type.baseName)) {
              indent.writeln(
                  'let ${field.name} = $fieldType.fromMap($mapValue as! [String: Any?])!');
            } else if (!hostDatatype.isBuiltin &&
                rootEnumNameSet.contains(field.type.baseName)) {
              indent.writeln(
                  'let ${field.name} = $fieldType(rawValue: $mapValue as! Int)!');
            } else {
              indent.writeln('let ${field.name} = $mapValue as! $fieldType');
            }
          }
        }

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

    indent.writeln(
        '/// Generated class from Pigeon that represents data sent in messages.');
    indent.write('struct ${klass.name} ');
    indent.scoped('{', '}', () {
      klass.fields.forEach(writeField);

      indent.writeln('');
      writeFromMap();
      writeToMap();
    });
  }

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

  void writeWrapResult() {
    indent.write('private func wrapResult(_ result: Any?) -> [String: Any?] ');
    indent.scoped('{', '}', () {
      indent.writeln('return ["result": result]');
    });
  }

  void writeWrapError() {
    indent.write(
        'private func wrapError(_ error: FlutterError) -> [String: Any?] ');
    indent.scoped('{', '}', () {
      indent.write('return ');
      indent.scoped('[', ']', () {
        indent.write('"error": ');
        indent.scoped('[', ']', () {
          indent.writeln('"${Keys.errorCode}": error.code,');
          indent.writeln('"${Keys.errorMessage}": error.message,');
          indent.writeln('"${Keys.errorDetails}": error.details');
        });
      });
    });
  }

  writeHeader();
  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) {
    _writeCodec(indent, api, root);
    indent.addln('');
    writeApi(api, root);
  }

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