// Copyright (c) 2018, 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' as ir;
import 'package:kernel/type_environment.dart' as ir;
import 'closure.dart';
import 'scope_visitor.dart';

class ScopeModel {
  final ClosureScopeModel? closureScopeModel;
  final VariableScopeModel? variableScopeModel;
  final EvaluationComplexity initializerComplexity;

  const ScopeModel({
    this.closureScopeModel,
    this.variableScopeModel,
    required this.initializerComplexity,
  });

  /// Inspect members and mark if those members capture any state that needs to
  /// be marked as free variables.
  factory ScopeModel.from(ir.Member node, ir.TypeEnvironment typeEnvironment) {
    ScopeModelBuilder builder = ScopeModelBuilder(typeEnvironment);
    return builder.computeModel(node);
  }
}

abstract class VariableScopeModel {
  VariableScope getScopeFor(ir.TreeNode node);
  Iterable<ir.VariableDeclaration> get assignedVariables;
}

class VariableScopeModelImpl implements VariableScopeModel {
  final Map<ir.TreeNode, VariableScopeImpl> _scopeMap = {};
  Set<ir.VariableDeclaration>? _assignedVariables;

  VariableScopeImpl createScopeFor(ir.TreeNode node) {
    return _scopeMap[node] ??= VariableScopeImpl();
  }

  void registerAssignedVariable(ir.VariableDeclaration node) {
    (_assignedVariables ??= {}).add(node);
  }

  @override
  VariableScope getScopeFor(ir.TreeNode node) {
    return _scopeMap[node]!;
  }

  @override
  Iterable<ir.VariableDeclaration> get assignedVariables =>
      _assignedVariables ?? <ir.VariableDeclaration>[];
}

/// Variable information for a scope.
abstract class VariableScope {
  /// Returns the set of [ir.VariableDeclaration]s that have been assigned to in
  /// this scope.
  Iterable<ir.VariableDeclaration> get assignedVariables;

  /// Returns `true` if this scope has a [ir.ContinueSwitchStatement].
  bool get hasContinueSwitch;
}

class VariableScopeImpl implements VariableScope {
  List<VariableScope>? _subScopes;
  Set<ir.VariableDeclaration>? _assignedVariables;
  @override
  bool hasContinueSwitch = false;

  void addSubScope(VariableScope scope) {
    _subScopes ??= <VariableScope>[];
    _subScopes!.add(scope);
  }

  void registerAssignedVariable(ir.VariableDeclaration variable) {
    _assignedVariables ??= <ir.VariableDeclaration>{};
    _assignedVariables!.add(variable);
  }

  @override
  Iterable<ir.VariableDeclaration> get assignedVariables sync* {
    if (_assignedVariables != null) {
      yield* _assignedVariables!;
    }
    if (_subScopes != null) {
      for (VariableScope subScope in _subScopes!) {
        yield* subScope.assignedVariables;
      }
    }
  }
}

mixin VariableCollectorMixin {
  VariableScopeImpl? currentVariableScope;
  VariableScopeModelImpl variableScopeModel = VariableScopeModelImpl();

  void visitInVariableScope(ir.TreeNode root, void Function() f) {
    VariableScopeImpl? oldScope = currentVariableScope;
    final newScope = currentVariableScope = variableScopeModel.createScopeFor(
      root,
    );
    oldScope?.addSubScope(newScope);
    f();
    currentVariableScope = oldScope;
  }

  void registerAssignedVariable(ir.VariableDeclaration node) {
    currentVariableScope?.registerAssignedVariable(node);
    variableScopeModel.registerAssignedVariable(node);
  }

  void registerContinueSwitch() {
    currentVariableScope?.hasContinueSwitch = true;
  }
}
