// 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.

library fasta.function_type_builder;

import 'package:kernel/ast.dart'
    show
        DartType,
        DynamicType,
        FunctionType,
        NamedType,
        Supertype,
        TypeParameter,
        TypedefType;

import '../fasta_codes.dart' show messageSupertypeIsFunction, noLength;

import '../source/source_library_builder.dart';

import 'formal_parameter_builder.dart';
import 'library_builder.dart';
import 'nullability_builder.dart';
import 'type_builder.dart';
import 'type_variable_builder.dart';

class FunctionTypeBuilder extends TypeBuilder {
  final TypeBuilder? returnType;
  final List<TypeVariableBuilder>? typeVariables;
  final List<FormalParameterBuilder>? formals;
  final NullabilityBuilder nullabilityBuilder;
  final Uri? fileUri;
  final int charOffset;

  FunctionTypeBuilder(this.returnType, this.typeVariables, this.formals,
      this.nullabilityBuilder, this.fileUri, this.charOffset);

  @override
  String? get name => null;

  @override
  String get debugName => "Function";

  bool get isVoidType => false;

  @override
  StringBuffer printOn(StringBuffer buffer) {
    if (typeVariables != null) {
      buffer.write("<");
      bool isFirst = true;
      for (TypeVariableBuilder t in typeVariables!) {
        if (!isFirst) {
          buffer.write(", ");
        } else {
          isFirst = false;
        }
        buffer.write(t.name);
      }
      buffer.write(">");
    }
    buffer.write("(");
    if (formals != null) {
      bool isFirst = true;
      for (FormalParameterBuilder t in formals!) {
        if (!isFirst) {
          buffer.write(", ");
        } else {
          isFirst = false;
        }
        buffer.write(t.fullNameForErrors);
      }
    }
    buffer.write(") ->");
    nullabilityBuilder.writeNullabilityOn(buffer);
    buffer.write(" ");
    buffer.write(returnType?.fullNameForErrors);
    return buffer;
  }

  FunctionType build(LibraryBuilder library,
      {TypedefType? origin, bool? nonInstanceContext}) {
    DartType builtReturnType =
        returnType?.build(library, nonInstanceContext: nonInstanceContext) ??
            const DynamicType();
    List<DartType> positionalParameters = <DartType>[];
    List<NamedType>? namedParameters;
    int requiredParameterCount = 0;
    if (formals != null) {
      for (FormalParameterBuilder formal in formals!) {
        DartType type = formal.type
                ?.build(library, nonInstanceContext: nonInstanceContext) ??
            const DynamicType();
        if (formal.isPositional) {
          positionalParameters.add(type);
          if (formal.isRequired) requiredParameterCount++;
        } else if (formal.isNamed) {
          namedParameters ??= <NamedType>[];
          namedParameters.add(new NamedType(formal.name, type,
              isRequired: formal.isNamedRequired));
        }
      }
      if (namedParameters != null) {
        namedParameters.sort();
      }
    }
    List<TypeParameter>? typeParameters;
    if (typeVariables != null) {
      typeParameters = <TypeParameter>[];
      for (TypeVariableBuilder t in typeVariables!) {
        typeParameters.add(t.parameter);
        // Build the bound to detect cycles in typedefs.
        t.bound?.build(library, origin: origin);
      }
    }
    return new FunctionType(positionalParameters, builtReturnType,
        nullabilityBuilder.build(library),
        namedParameters: namedParameters ?? const <NamedType>[],
        typeParameters: typeParameters ?? const <TypeParameter>[],
        requiredParameterCount: requiredParameterCount,
        typedefType: origin);
  }

  Supertype? buildSupertype(
      LibraryBuilder library, int charOffset, Uri fileUri) {
    library.addProblem(
        messageSupertypeIsFunction, charOffset, noLength, fileUri);
    return null;
  }

  Supertype? buildMixedInType(
      LibraryBuilder library, int charOffset, Uri fileUri) {
    return buildSupertype(library, charOffset, fileUri);
  }

  FunctionTypeBuilder clone(
      List<TypeBuilder> newTypes,
      SourceLibraryBuilder contextLibrary,
      TypeParameterScopeBuilder contextDeclaration) {
    List<TypeVariableBuilder>? clonedTypeVariables;
    if (typeVariables != null) {
      clonedTypeVariables =
          contextLibrary.copyTypeVariables(typeVariables!, contextDeclaration);
    }
    List<FormalParameterBuilder>? clonedFormals;
    if (formals != null) {
      clonedFormals =
          new List<FormalParameterBuilder>.generate(formals!.length, (int i) {
        FormalParameterBuilder formal = formals![i];
        return formal.clone(newTypes, contextLibrary, contextDeclaration);
      }, growable: false);
    }
    FunctionTypeBuilder newType = new FunctionTypeBuilder(
        returnType?.clone(newTypes, contextLibrary, contextDeclaration),
        clonedTypeVariables,
        clonedFormals,
        nullabilityBuilder,
        fileUri,
        charOffset);
    newTypes.add(newType);
    return newType;
  }

  FunctionTypeBuilder withNullabilityBuilder(
      NullabilityBuilder nullabilityBuilder) {
    return new FunctionTypeBuilder(returnType, typeVariables, formals,
        nullabilityBuilder, fileUri, charOffset);
  }
}
