// Copyright (c) 2025, 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 'dart:ffi';

import 'package:logging/logging.dart';

import 'code_generator.dart';
import 'code_generator/scope.dart';
import 'config_provider/config.dart';
import 'config_provider/config_types.dart';
import 'config_provider/spec_utils.dart';
import 'header_parser/clang_bindings/clang_bindings.dart' show Clang;
import 'header_parser/utils.dart';

/// Wrapper around various ffigen-wide variables.
class Context {
  final Logger logger;
  final Config config;
  final CursorIndex cursorIndex;
  final bindingsIndex = BindingsIndex();
  final savedMacros = <String, Macro>{};
  final unnamedEnumConstants = <Constant>[];
  late final ObjCBuiltInFunctions objCBuiltInFunctions;
  bool hasSourceErrors = false;
  final reportedCommentRanges = <((String, int), (String, int))>{};
  final libs = LibraryImports();
  late final compilerOpts = config.compilerOpts ?? defaultCompilerOpts(logger);
  final Scope rootScope = Scope.createRoot('root');
  final Scope rootObjCScope = Scope.createRoot('objc_root');
  late final ExtraSymbols extraSymbols;

  Context(this.logger, FfiGenerator generator, {Uri? libclangDylib})
    : config = Config(generator),
      cursorIndex = CursorIndex(logger) {
    objCBuiltInFunctions = ObjCBuiltInFunctions(
      this,
      config.wrapperName,
      // ignore: deprecated_member_use_from_same_package
      generator.objectiveC?.generateForPackageObjectiveC ?? false,
    );
    final libclangDylibPath =
        // ignore: deprecated_member_use_from_same_package
        generator.libclangDylib?.toFilePath() ??
        libclangDylib?.toFilePath() ??
        findDylibAtDefaultLocations(logger);
    _clang ??= Clang(DynamicLibrary.open(libclangDylibPath));
  }
}

/// The clang bindings.
//
// Ideally this would be in the Context, but the plumbing needed would be
// excessive. The point of putting globals in the Context is to allow multiple
// concurrent FfiGen runs without any risk of clobbering global state. The
// clang bindings are loaded from a dylib specified by the config, so it's
// possible that two different versions of clang could be loaded. But since we
// interact with clang through a stable API, there's no real danger of version
// skew. So the safest thing is to simply load clang the first time a Context
// is created, and reuse it for all subsequent runs.
Clang get clang => _clang!;
Clang? _clang;

class LibraryImports {
  String get ffiLibraryPrefix => prefix(ffiImport);
  String get ffiPkgLibraryPrefix => prefix(ffiPkgImport);
  String get objcPkgPrefix => prefix(objcPkgImport);
  String get selfImportPrefix => prefix(selfImport);

  // Dedupe [lib] by name.
  LibraryImport canonicalize(LibraryImport lib) =>
      builtInLibraries[lib.name] ?? (_canonicalImports[lib.name] ??= lib);
  final _canonicalImports = <String, LibraryImport>{};

  // Mark an import as being used so that it can be assigned a prefix.
  void markUsed(LibraryImport lib) {
    assert(lib == canonicalize(lib));
    _used.add(lib);
  }

  Iterable<LibraryImport> get used => _used;

  final _used = <LibraryImport>{};

  // Call after all used imports have been marked by [markUsed]. Creates Symbols
  // for all the library prefixes used for codegen.
  void createSymbols(Scope scope) {
    for (final lib in _used) {
      scope.add(_prefixes[lib] = Symbol(lib.name));
    }

    _prefixesFilled = true;
  }

  bool _prefixesFilled = false;
  final _prefixes = <LibraryImport, Symbol>{};

  String prefix(LibraryImport lib) {
    assert(lib == canonicalize(lib));
    if (!_prefixesFilled) {
      // Before the prefixes have been filled, return a placeholder suitable for
      // debugging or hashing, but intentionally invalid as generated code.
      return '<${lib.name}>';
    }
    // If this null assert fails, it means that a library was used during code
    // generation that wasn't visited by MarkImportsVisitation, which is a bug.
    return _prefixes[lib]!.name;
  }

  void forceFillForTesting() {
    _used.addAll(builtInLibraries.values);
    for (final lib in _used) {
      _prefixes[lib] = Symbol(lib.name)..forceFillForTesting();
    }
    _prefixesFilled = true;
  }
}

typedef ExtraSymbols = ({
  Symbol? wrapperClassName,
  Symbol? lookupFuncName,
  // TODO(https://github.com/dart-lang/native/issues/1259): Make this nullable.
  Symbol symbolAddressVariableName,
});
