// Copyright 2020 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 'generator_tools.dart';

/// Options that control how Objective-C code will be generated.
class ObjcOptions {
  /// Parametric constructor for ObjcOptions.
  ObjcOptions({this.header, this.prefix});

  /// The path to the header that will get placed in the source filed (example:
  /// "foo.h").
  String header;

  /// Prefix that will be appended before all generated classes and protocols.
  String prefix;
}

String _className(String prefix, String className) {
  if (prefix != null) {
    return '$prefix$className';
  } else {
    return className;
  }
}

const Map<String, String> _objcTypeForDartTypeMap = <String, String>{
  'bool': 'NSNumber *',
  'int': 'NSNumber *',
  'String': 'NSString *',
  'double': 'NSNumber *',
  'Uint8List': 'FlutterStandardTypedData *',
  'Int32List': 'FlutterStandardTypedData *',
  'Int64List': 'FlutterStandardTypedData *',
  'Float64List': 'FlutterStandardTypedData *',
};

const Map<String, String> _propertyTypeForDartTypeMap = <String, String>{
  'String': 'copy',
  'bool': 'strong',
  'int': 'strong',
  'double': 'strong',
  'Uint8List': 'strong',
  'Int32List': 'strong',
  'Int64List': 'strong',
  'Float64List': 'strong',
};

String _objcTypeForDartType(String type) {
  return _objcTypeForDartTypeMap[type];
}

String _propertyTypeForDartType(String type) {
  final String result = _propertyTypeForDartTypeMap[type];
  if (result == null) {
    return 'assign';
  } else {
    return result;
  }
}

/// Generates the ".h" file for the AST represented by [root] to [sink] with the
/// provided [options].
void generateObjcHeader(ObjcOptions options, Root root, StringSink sink) {
  final Indent indent = Indent(sink);
  indent.writeln('// Autogenerated from Dartle.');
  indent.writeln('#import <Foundation/Foundation.h>');
  indent.writeln('@protocol FlutterBinaryMessenger;');
  indent.writeln('@class FlutterStandardTypedData;');
  indent.writeln('');

  for (Class klass in root.classes) {
    indent.writeln('@class ${_className(options.prefix, klass.name)};');
  }

  indent.writeln('');

  for (Class klass in root.classes) {
    indent.writeln(
        '@interface ${_className(options.prefix, klass.name)} : NSObject ');
    for (Field field in klass.fields) {
      final HostDatatype hostDatatype = getHostDatatype(
          field,
          root.classes,
          _objcTypeForDartType,
          (String x) => '${_className(options.prefix, x)} *');
      final String propertyType = hostDatatype.isBuiltin
          ? _propertyTypeForDartType(field.dataType)
          : 'strong';
      indent.writeln(
          '@property(nonatomic, $propertyType) ${hostDatatype.datatype} ${field.name};');
    }
    indent.writeln('@end');
    indent.writeln('');
  }

  for (Api api in root.apis) {
    final String apiName = _className(options.prefix, api.name);
    if (api.location == ApiLocation.host) {
      indent.writeln('@protocol $apiName');
      for (Method func in api.methods) {
        final String returnType = _className(options.prefix, func.returnType);
        final String argType = _className(options.prefix, func.argType);
        indent.writeln('-($returnType *)${func.name}:($argType*)input;');
      }
      indent.writeln('@end');
      indent.writeln('');
      indent.writeln(
          'extern void ${apiName}Setup(id<FlutterBinaryMessenger> binaryMessenger, id<$apiName> api);');
      indent.writeln('');
    } else if (api.location == ApiLocation.flutter) {
      indent.writeln('@interface $apiName : NSObject');
      indent.writeln(
          '- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;');
      for (Method func in api.methods) {
        final String returnType = _className(options.prefix, func.returnType);
        final String argType = _className(options.prefix, func.argType);
        indent.writeln(
            '- (void)${func.name}:($argType*)input completion:(void(^)($returnType*, NSError*))completion;');
      }
      indent.writeln('@end');
    }
  }
}

String _dictGetter(
    List<String> classnames, String dict, Field field, String prefix) {
  if (classnames.contains(field.dataType)) {
    String className = field.dataType;
    if (prefix != null) {
      className = '$prefix$className';
    }
    return '[$className fromMap:$dict[@"${field.name}"]]';
  } else {
    return '$dict[@"${field.name}"]';
  }
}

String _dictValue(List<String> classnames, Field field) {
  if (classnames.contains(field.dataType)) {
    return '[self.${field.name} toMap]';
  } else {
    return 'self.${field.name}';
  }
}

void _writeHostApiSource(Indent indent, ObjcOptions options, Api api) {
  assert(api.location == ApiLocation.host);
  final String apiName = _className(options.prefix, api.name);
  indent.write(
      'void ${apiName}Setup(id<FlutterBinaryMessenger> binaryMessenger, id<$apiName> api) ');
  indent.scoped('{', '}', () {
    for (Method func in api.methods) {
      indent.write('');
      indent.scoped('{', '}', () {
        indent.writeln('FlutterBasicMessageChannel *channel =');
        indent.inc();
        indent.writeln('[FlutterBasicMessageChannel');
        indent.inc();
        indent
            .writeln('messageChannelWithName:@"${makeChannelName(api, func)}"');
        indent.writeln('binaryMessenger:binaryMessenger];');
        indent.dec();
        indent.dec();

        indent.write(
            '[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) ');
        indent.scoped('{', '}];', () {
          final String argType = _className(options.prefix, func.argType);
          final String returnType = _className(options.prefix, func.returnType);
          indent.writeln('$argType *input = [$argType fromMap:message];');
          indent.writeln('$returnType *output = [api ${func.name}:input];');
          indent.writeln('callback([output toMap]);');
        });
      });
    }
  });
}

void _writeFlutterApiSource(Indent indent, ObjcOptions options, Api api) {
  assert(api.location == ApiLocation.flutter);
  final String apiName = _className(options.prefix, api.name);
  indent.writeln('@interface $apiName ()');
  indent.writeln(
      '@property (nonatomic, strong) NSObject<FlutterBinaryMessenger>* binaryMessenger;');
  indent.writeln('@end');
  indent.addln('');
  indent.writeln('@implementation $apiName');
  indent.write(
      '- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger>*)binaryMessenger ');
  indent.scoped('{', '}', () {
    indent.writeln('self = [super init];');
    indent.write('if (self) ');
    indent.scoped('{', '}', () {
      indent.writeln('self.binaryMessenger = binaryMessenger;');
    });
    indent.writeln('return self;');
  });
  indent.addln('');
  for (Method func in api.methods) {
    final String returnType = _className(options.prefix, func.returnType);
    final String argType = _className(options.prefix, func.argType);
    indent.write(
        '- (void)${func.name}:($argType*)input completion:(void(^)($returnType*, NSError*))completion ');
    indent.scoped('{', '}', () {
      indent.writeln('FlutterBasicMessageChannel *channel =');
      indent.inc();
      indent.writeln('[FlutterBasicMessageChannel');
      indent.inc();
      indent.writeln('messageChannelWithName:@"${makeChannelName(api, func)}"');
      indent.writeln('binaryMessenger:self.binaryMessenger];');
      indent.dec();
      indent.dec();
      indent.writeln('NSDictionary* inputMap = [input toMap];');
      indent.write('[channel sendMessage:inputMap reply:^(id reply) ');
      indent.scoped('{', '}];', () {
        indent.writeln('NSDictionary* outputMap = reply;');
        indent
            .writeln('$returnType * output = [$returnType fromMap:outputMap];');
        indent.writeln('completion(output, nil);');
      });
    });
  }
  indent.writeln('@end');
}

/// Generates the ".m" file for the AST represented by [root] to [sink] with the
/// provided [options].
void generateObjcSource(ObjcOptions options, Root root, StringSink sink) {
  final Indent indent = Indent(sink);
  final List<String> classnames =
      root.classes.map((Class x) => x.name).toList();

  indent.writeln('// Autogenerated from Dartle.');
  indent.writeln('#import "${options.header}"');
  indent.writeln('#import <Flutter/Flutter.h>');
  indent.writeln('');

  for (Class klass in root.classes) {
    final String className = _className(options.prefix, klass.name);
    indent.writeln('@interface $className ()');
    indent.writeln('+($className*)fromMap:(NSDictionary*)dict;');
    indent.writeln('-(NSDictionary*)toMap;');
    indent.writeln('@end');
  }

  indent.writeln('');

  for (Class klass in root.classes) {
    final String className = _className(options.prefix, klass.name);
    indent.writeln('@implementation $className');
    indent.write('+($className*)fromMap:(NSDictionary*)dict ');
    indent.scoped('{', '}', () {
      indent.writeln('$className* result = [[$className alloc] init];');
      for (Field field in klass.fields) {
        indent.writeln(
            'result.${field.name} = ${_dictGetter(classnames, 'dict', field, options.prefix)};');
      }
      indent.writeln('return result;');
    });
    indent.write('-(NSDictionary*)toMap ');
    indent.scoped('{', '}', () {
      indent.write('return [NSDictionary dictionaryWithObjectsAndKeys:');
      for (Field field in klass.fields) {
        indent.add(_dictValue(classnames, field) + ', @"${field.name}", ');
      }
      indent.addln('nil];');
    });
    indent.writeln('@end');
    indent.writeln('');
  }

  for (Api api in root.apis) {
    if (api.location == ApiLocation.host) {
      _writeHostApiSource(indent, options, api);
    } else if (api.location == ApiLocation.flutter) {
      _writeFlutterApiSource(indent, options, api);
    }
  }
}
