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

import 'package:kernel/ast.dart' show LibraryDependency;

import '../base/combinator.dart';
import '../base/messages.dart';
import '../base/name_space.dart';
import '../base/scope.dart';
import '../base/uri_offset.dart';
import '../kernel/load_library_builder.dart' show LoadLibraryBuilder;
import '../kernel/utils.dart';
import '../source/source_library_builder.dart';
import 'builder.dart';
import 'declaration_builders.dart';
import 'library_builder.dart';

class PrefixBuilder extends BuilderImpl {
  final String name;

  final NameSpace _prefixNameSpace = new NameSpaceImpl();

  late final LookupScope _prefixScope =
      new NameSpaceLookupScope(_prefixNameSpace, ScopeKind.library, "top");

  @override
  final SourceLibraryBuilder parent;

  final bool deferred;

  @override
  final Uri fileUri;

  @override
  final int fileOffset;

  final LoadLibraryBuilder? loadLibraryBuilder;

  final bool isWildcard;

  PrefixBuilder(this.name, this.deferred, this.parent, this.loadLibraryBuilder,
      {required this.fileUri,
      required int prefixOffset,
      required int importOffset})
      : fileOffset = prefixOffset,
        isWildcard = name == '_' {
    assert(deferred == (loadLibraryBuilder != null),
        "LoadLibraryBuilder must be provided iff prefix is deferred.");
    if (loadLibraryBuilder != null) {
      addToPrefixScope('loadLibrary', loadLibraryBuilder!,
          importOffset: importOffset, prefixOffset: prefixOffset);
    }
  }

  LookupScope get prefixScope => _prefixScope;

  void forEachExtension(void Function(ExtensionBuilder) f) {
    _prefixNameSpace.forEachLocalExtension(f);
  }

  LibraryDependency? get dependency => loadLibraryBuilder?.importDependency;

  /// Lookup a member with [name] in the export scope.
  Builder? lookup(String name, int charOffset, Uri fileUri) {
    return _prefixScope.lookupGetable(name, charOffset, fileUri);
  }

  void addToPrefixScope(String name, Builder member,
      {required int importOffset, required int prefixOffset}) {
    if (deferred && member is ExtensionBuilder) {
      parent.addProblem(templateDeferredExtensionImport.withArguments(name),
          importOffset, noLength, fileUri);
    }

    Builder? existing =
        _prefixNameSpace.lookupLocalMember(name, setter: member.isSetter);
    Builder result;
    if (existing != null) {
      result = computeAmbiguousDeclarationForImport(
          parent, name, existing, member,
          uriOffset: new UriOffset(fileUri, prefixOffset));
    } else {
      result = member;
    }
    _prefixNameSpace.addLocalMember(name, result, setter: member.isSetter);
    if (member is ExtensionBuilder) {
      _prefixNameSpace.addExtension(member);
    }
  }

  @override
  // Coverage-ignore(suite): Not run.
  String get fullNameForErrors => name;
}

class PrefixFragment {
  final String name;
  final SourceCompilationUnit importer;
  final CompilationUnit? imported;
  final List<CombinatorBuilder>? combinators;
  final bool deferred;
  final Uri fileUri;
  final int importOffset;
  final int prefixOffset;

  PrefixBuilder? _builder;

  PrefixFragment({
    required this.name,
    required this.importer,
    required this.imported,
    required this.combinators,
    required this.deferred,
    required this.fileUri,
    required this.importOffset,
    required this.prefixOffset,
  });

  PrefixBuilder createPrefixBuilder() {
    LoadLibraryBuilder? loadLibraryBuilder;
    if (deferred) {
      loadLibraryBuilder = new LoadLibraryBuilder(
          importer.libraryBuilder,
          prefixOffset,
          imported!,
          name,
          importOffset,
          toCombinators(combinators));
    }

    return builder = new PrefixBuilder(
        name, deferred, importer.libraryBuilder, loadLibraryBuilder,
        fileUri: fileUri,
        prefixOffset: prefixOffset,
        importOffset: importOffset);
  }

  PrefixBuilder get builder {
    assert(_builder != null, "Builder has not been computed for $this.");
    return _builder!;
  }

  void set builder(PrefixBuilder value) {
    assert(_builder == null, "Builder has already been computed for $this.");
    _builder = value;
  }

  @override
  String toString() => '$runtimeType($name,$fileUri,$importOffset)';
}
