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

part of '../protoc.dart';

class GrpcServiceGenerator {
  final ServiceDescriptorProto _descriptor;

  /// The generator of the .pb.dart file that will contain this service.
  final FileGenerator fileGen;

  final int _serviceIndex;

  /// The message types needed directly by this service.
  ///
  /// The key is the fully qualified name.
  /// Populated by [resolve].
  final Map<String, MessageGenerator> _deps = {};

  /// Maps each undefined type to a string describing its location.
  ///
  /// Populated by [resolve].
  final Map<String, String> _undefinedDeps = {};

  /// Fully-qualified gRPC service name.
  late final String _fullServiceName;

  /// Dart class name for client stub.
  late final String _clientClassname;

  /// Dart class name for server stub.
  late final String _serviceClassname;

  /// List of gRPC methods.
  final List<_GrpcMethod> _methods = [];

  late final List<int> _serviceDescriptorPath = [
    ...fileGen.fieldPath,
    ClientApiGenerator.fileDescriptorServiceTag,
    _serviceIndex,
  ];

  GrpcServiceGenerator(this._descriptor, this.fileGen, this._serviceIndex) {
    final name = _descriptor.name;
    final package = fileGen.package;

    if (package.isNotEmpty) {
      _fullServiceName = '$package.$name';
    } else {
      _fullServiceName = name;
    }

    // avoid: ClientClient
    _clientClassname = name.endsWith('Client') ? name : '${name}Client';
    // avoid: ServiceServiceBase
    _serviceClassname =
        name.endsWith('Service') ? '${name}Base' : '${name}ServiceBase';
  }

  /// Finds all message types used by this service.
  ///
  /// Puts the types found in [_deps]. If a type name can't be resolved, puts it
  /// in [_undefinedDeps].
  /// Precondition: messages have been registered and resolved.
  void resolve(GenerationContext ctx) {
    for (final method in _descriptor.method) {
      _methods.add(_GrpcMethod(this, ctx, method));
    }
  }

  /// Adds a dependency on the given message type.
  ///
  /// If the type name can't be resolved, adds it to [_undefinedDeps].
  void _addDependency(GenerationContext ctx, String fqname, String location) {
    if (_deps.containsKey(fqname)) return; // Already added.

    final mg = ctx.getFieldType(fqname) as MessageGenerator?;
    if (mg == null) {
      _undefinedDeps[fqname] = location;
      return;
    }
    mg.checkResolved();
    _deps[mg.dottedName] = mg;
  }

  /// Adds dependencies of [generate] to [imports].
  ///
  /// For each .pb.dart file that the generated code needs to import,
  /// add its generator.
  void addImportsTo(Set<FileGenerator> imports) {
    for (final mg in _deps.values) {
      imports.add(mg.fileGen);
    }
  }

  /// Returns the Dart class name to use for a message type.
  ///
  /// Throws an exception if it can't be resolved.
  String _getDartClassName(String fqname) {
    final mg = _deps[fqname];
    if (mg == null) {
      final location = _undefinedDeps[fqname];
      // TODO(nichite): Throw more actionable error.
      throw 'FAILURE: Unknown type reference ($fqname) for $location';
    }
    return '${mg.fileImportPrefix}.${mg.classname}';
  }

  void generate(IndentingWriter out) {
    _generateClient(out);
    out.println();
    _generateService(out);
  }

  void _generateClient(IndentingWriter out) {
    final commentBlock = fileGen.commentBlock(_serviceDescriptorPath);
    if (commentBlock != null) {
      out.println(commentBlock);
    }
    if (_descriptor.options.deprecated) {
      out.println(
          "@$coreImportPrefix.Deprecated('This service is deprecated')");
    }
    out.println("@$protobufImportPrefix.GrpcServiceName('$_fullServiceName')");
    out.addBlock('class $_clientClassname extends $_client {', '}', () {
      // Look for and generate default_host info.
      final defaultHost = _descriptor.options.defaultHost;
      if (defaultHost != null) {
        out.println('/// The hostname for this service.');
        out.println("static const $_string defaultHost = '$defaultHost';");
        out.println();
      }

      // Look for and generate oauth_scopes info.
      final oauthScopes = _descriptor.options.oauthScopes;
      if (oauthScopes != null) {
        out.println('/// OAuth scopes needed for the client.');
        out.println('static const $_list<$_string> oauthScopes = [');
        for (final scope in oauthScopes.split(',')) {
          out.println("  '$scope',");
        }
        out.println('];');
        out.println();
      }

      for (final method in _methods) {
        method.generateClientMethodDescriptor(out);
      }
      out.println();
      out.println(
          '$_clientClassname(super.channel, {super.options, super.interceptors});');
      for (var i = 0; i < _methods.length; i++) {
        _methods[i].generateClientStub(out, this, i);
      }
    });
  }

  void _generateService(IndentingWriter out) {
    out.println("@$protobufImportPrefix.GrpcServiceName('$_fullServiceName')");
    out.addBlock('abstract class $_serviceClassname extends $_service {', '}',
        () {
      out.println(
          "$coreImportPrefix.String get \$name => '$_fullServiceName';");
      out.println();
      out.addBlock('$_serviceClassname() {', '}', () {
        for (final method in _methods) {
          method.generateServiceMethodRegistration(out);
        }
      });
      out.println();
      for (final method in _methods) {
        method.generateServiceMethodPreamble(out);
      }
      for (final method in _methods) {
        method.generateServiceMethodStub(out);
      }
    });
  }

  static final String _callOptions = '$grpcImportPrefix.CallOptions';
  static final String _client = '$grpcImportPrefix.Client';
  static final String _service = '$grpcImportPrefix.Service';
  static final String _list = '$coreImportPrefix.List';
  static final String _string = '$coreImportPrefix.String';
}

class _GrpcMethod {
  final String _grpcName;
  final String _dartName;
  final String _serviceName;

  final bool _clientStreaming;
  final bool _serverStreaming;

  final String _requestType;
  final String _responseType;

  final String _argumentType;
  final String _clientReturnType;
  final String _serverReturnType;

  final bool _deprecated;

  _GrpcMethod._(
      this._grpcName,
      this._dartName,
      this._serviceName,
      this._clientStreaming,
      this._serverStreaming,
      this._requestType,
      this._responseType,
      this._argumentType,
      this._clientReturnType,
      this._serverReturnType,
      this._deprecated);

  factory _GrpcMethod(GrpcServiceGenerator service, GenerationContext ctx,
      MethodDescriptorProto method) {
    final grpcName = method.name;
    final dartName = lowerCaseFirstLetter(grpcName);

    final clientStreaming = method.clientStreaming;
    final serverStreaming = method.serverStreaming;

    service._addDependency(ctx, method.inputType, 'input type of $grpcName');
    service._addDependency(ctx, method.outputType, 'output type of $grpcName');

    final requestType = service._getDartClassName(method.inputType);
    final responseType = service._getDartClassName(method.outputType);

    final argumentType =
        clientStreaming ? '$_stream<$requestType>' : requestType;
    final clientReturnType = serverStreaming
        ? '$_responseStream<$responseType>'
        : '$_responseFuture<$responseType>';
    final serverReturnType =
        serverStreaming ? '$_stream<$responseType>' : '$_future<$responseType>';

    final deprecated = method.options.deprecated;

    return _GrpcMethod._(
        grpcName,
        dartName,
        service._fullServiceName,
        clientStreaming,
        serverStreaming,
        requestType,
        responseType,
        argumentType,
        clientReturnType,
        serverReturnType,
        deprecated);
  }

  void generateClientMethodDescriptor(IndentingWriter out) {
    out.println(
        'static final _\$$_dartName = $_clientMethod<$_requestType, $_responseType>(');
    out.println('    \'/$_serviceName/$_grpcName\',');
    out.println('    ($_requestType value) => value.writeToBuffer(),');
    out.println(
        '    ($coreImportPrefix.List<$coreImportPrefix.int> value) => $_responseType.fromBuffer(value));');
  }

  List<int> _methodDescriptorPath(GrpcServiceGenerator generator, int index) {
    return [
      ...generator._serviceDescriptorPath,
      ClientApiGenerator.serviceDescriptorMethodTag,
      index,
    ];
  }

  void generateClientStub(IndentingWriter out,
      GrpcServiceGenerator serviceGenerator, int methodIndex) {
    out.println();
    final commentBlock = serviceGenerator.fileGen
        .commentBlock(_methodDescriptorPath(serviceGenerator, methodIndex));
    if (commentBlock != null) {
      out.println(commentBlock);
    }
    if (_deprecated) {
      out.println(
          '@$coreImportPrefix.Deprecated(\'This method is deprecated\')');
    }
    out.addBlock(
        '$_clientReturnType $_dartName($_argumentType request, {${GrpcServiceGenerator._callOptions}? options}) {',
        '}', () {
      if (_clientStreaming && _serverStreaming) {
        out.println(
            'return \$createStreamingCall(_\$$_dartName, request, options: options);');
      } else if (_clientStreaming && !_serverStreaming) {
        out.println(
            'return \$createStreamingCall(_\$$_dartName, request, options: options).single;');
      } else if (!_clientStreaming && _serverStreaming) {
        out.println(
            'return \$createStreamingCall(_\$$_dartName, $_stream.fromIterable([request]), options: options);');
      } else {
        out.println(
            'return \$createUnaryCall(_\$$_dartName, request, options: options);');
      }
    });
  }

  void generateServiceMethodRegistration(IndentingWriter out) {
    out.println('\$addMethod($_serviceMethod<$_requestType, $_responseType>(');
    out.println('    \'$_grpcName\',');
    out.println('    $_dartName${_clientStreaming ? '' : '_Pre'},');
    out.println('    $_clientStreaming,');
    out.println('    $_serverStreaming,');
    out.println(
        '    ($coreImportPrefix.List<$coreImportPrefix.int> value) => $_requestType.fromBuffer(value),');
    out.println('    ($_responseType value) => value.writeToBuffer()));');
  }

  void generateServiceMethodPreamble(IndentingWriter out) {
    if (_clientStreaming) return;

    out.addBlock(
        '$_serverReturnType ${_dartName}_Pre($_serviceCall \$call, $_future<$_requestType> \$request) async${_serverStreaming ? '*' : ''} {',
        '}', () {
      if (_serverStreaming) {
        out.println('yield* $_dartName(\$call, await \$request);');
      } else {
        out.println('return $_dartName(\$call, await \$request);');
      }
    });
    out.println();
  }

  void generateServiceMethodStub(IndentingWriter out) {
    out.println(
        '$_serverReturnType $_dartName($_serviceCall call, $_argumentType request);');
  }

  static final String _serviceCall = '$grpcImportPrefix.ServiceCall';
  static final String _serviceMethod = '$grpcImportPrefix.ServiceMethod';
  static final String _clientMethod = '$grpcImportPrefix.ClientMethod';
  static final String _future = '$asyncImportPrefix.Future';
  static final String _stream = '$asyncImportPrefix.Stream';
  static final String _responseFuture = '$grpcImportPrefix.ResponseFuture';
  static final String _responseStream = '$grpcImportPrefix.ResponseStream';
}

extension on ServiceOptions {
  String? get defaultHost => getExtension(Client.defaultHost) as String?;

  String? get oauthScopes => getExtension(Client.oauthScopes) as String?;
}
