// Copyright (c) 2020, 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/class_hierarchy.dart';
import 'package:kernel/kernel.dart';

/// Provides support for "single widget reloads" in Flutter, by determining if
/// a partial component contains single change to the class body of a
/// StatelessWidget, StatefulWidget, or State subtype.
class WidgetCache {
  /// Create a [WidgetCache] from a [Component] containing the flutter
  /// framework.
  WidgetCache(Component fullComponent) {
    Library? frameworkLibrary;
    for (Library library in fullComponent.libraries) {
      if (library.importUri == _frameworkLibrary) {
        frameworkLibrary = library;
        break;
      }
    }
    if (frameworkLibrary == null) {
      return;
    }
    _locatedClassDeclarations(frameworkLibrary);
    _frameworkTypesLocated =
        _statefulWidget != null && _state != null && _statelessWidget != null;
  }

  static const String _stateClassName = 'State';
  static const String _statefulWidgetClassName = 'StatefulWidget';
  static const String _statelessWidgetClassName = 'StatelessWidget';

  Class? _statelessWidget;
  Class? _state;
  Class? _statefulWidget;
  bool _frameworkTypesLocated = false;

  static final Uri _frameworkLibrary =
      Uri.parse('package:flutter/src/widgets/framework.dart');

  /// Mark [uri] as invalidated.
  void invalidate(Uri uri) {
    _invalidatedLibraries.add(uri);
  }

  /// Reset the invalidated libraries.
  void reset() {
    _invalidatedLibraries.clear();
  }

  final List<Uri> _invalidatedLibraries = <Uri>[];

  /// Determine if any changes to [partialComponent] were located entirely
  /// within the class body of a single `StatefulWidget`, `StatelessWidget` or
  /// `State` subtype.
  ///
  /// Returns the class name if located, otherwise `null`.
  String? checkSingleWidgetTypeModified(
    Component? lastGoodComponent,
    Component partialComponent,
    ClassHierarchy classHierarchy,
  ) {
    if (!_frameworkTypesLocated ||
        lastGoodComponent == null ||
        _invalidatedLibraries.length != 1) {
      return null;
    }
    Uri importUri = _invalidatedLibraries[0];
    Library? library;
    for (Library candidateLibrary in partialComponent.libraries) {
      if (candidateLibrary.importUri == importUri) {
        library = candidateLibrary;
        break;
      }
    }
    if (library == null) {
      return null;
    }
    List<int> oldSource =
        lastGoodComponent.uriToSource[library.fileUri]!.source;
    List<int> newSource = partialComponent.uriToSource[library.fileUri]!.source;
    // Library was added and does not exist in the old component.
    // ignore: unnecessary_null_comparison
    if (oldSource == null) {
      return null;
    }
    int newStartIndex = 0;
    int newEndIndex = newSource.length - 1;
    int oldStartIndex = 0;
    int oldEndIndex = oldSource.length - 1;

    while (newStartIndex < newEndIndex && oldStartIndex < oldEndIndex) {
      if (newSource[newStartIndex] != oldSource[oldStartIndex]) {
        break;
      }
      newStartIndex += 1;
      oldStartIndex += 1;
    }
    while (newEndIndex > newStartIndex && oldEndIndex > oldStartIndex) {
      if (newSource[newEndIndex] != oldSource[oldEndIndex]) {
        break;
      }
      newEndIndex -= 1;
      oldEndIndex -= 1;
    }

    Class? newClass =
        _locateContainingClass(library, newStartIndex, newEndIndex);
    if (newClass == null) {
      return null;
    }

    Library oldLibrary =
        lastGoodComponent.libraries.firstWhere((Library library) {
      return library.importUri == importUri;
    });

    Class? oldClass =
        _locateContainingClass(oldLibrary, oldStartIndex, oldEndIndex);

    if (oldClass == null || oldClass.name != newClass.name) {
      return null;
    }

    // Update the class references to stateless, stateful, and state classes.
    for (Library library in classHierarchy.knownLibraries) {
      if (library.importUri == _frameworkLibrary) {
        _locatedClassDeclarations(library);
      }
    }

    if (classHierarchy.isSubclassOf(newClass, _statelessWidget!) ||
        classHierarchy.isSubclassOf(newClass, _statefulWidget!)) {
      if (classHierarchy.isExtended(newClass) ||
          classHierarchy.isUsedAsMixin(newClass)) {
        return null;
      }
      return newClass.name;
    }

    // For changes to State classes, locate the name of the corresponding
    // StatefulWidget that is provided as a type parameter. If the bounds are
    // StatefulWidget itself, fail as that indicates the type was not
    // specified.
    Supertype? stateSuperType =
        classHierarchy.getClassAsInstanceOf(newClass, _state!);
    if (stateSuperType != null) {
      if (stateSuperType.typeArguments.length != 1) {
        return null;
      }
      DartType widgetType = stateSuperType.typeArguments[0];
      if (widgetType is InterfaceType) {
        Class statefulWidgetType = widgetType.classNode;
        if (statefulWidgetType.name == _statefulWidgetClassName) {
          return null;
        }
        if (classHierarchy.isExtended(statefulWidgetType) ||
            classHierarchy.isUsedAsMixin(statefulWidgetType)) {
          return null;
        }
        return statefulWidgetType.name;
      }
    }

    return null;
  }

  // Locate the that fully contains the edit range, or null.
  Class? _locateContainingClass(
      Library library, int startOffset, int endOffset) {
    for (Class classDeclaration in library.classes) {
      if (classDeclaration.startFileOffset <= startOffset &&
          classDeclaration.fileEndOffset >= endOffset) {
        return classDeclaration;
      }
    }
    return null;
  }

  void _locatedClassDeclarations(Library library) {
    for (Class classDeclaration in library.classes) {
      if (classDeclaration.name == _statelessWidgetClassName) {
        _statelessWidget = classDeclaration;
      } else if (classDeclaration.name == _statefulWidgetClassName) {
        _statefulWidget = classDeclaration;
      } else if (classDeclaration.name == _stateClassName) {
        _state = classDeclaration;
      }
    }
  }
}
