// 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?.path == 'flutter/src/widgets/framework.dart') {
        frameworkLibrary = library;
        break;
      }
    }
    if (frameworkLibrary == null) {
      return;
    }
    for (Class classDeclaration in frameworkLibrary.classes) {
      if (classDeclaration.name == _statelessWidgetClassName) {
        _statelessWidget = classDeclaration;
      } else if (classDeclaration.name == _statefulWidgetClassName) {
        _statefulWidget = classDeclaration;
      } else if (classDeclaration.name == _stateClassName) {
        _state = classDeclaration;
      }
    }
    _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;

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

    if (classHierarchy.isSubclassOf(newClass, _statelessWidget) ||
        classHierarchy.isSubclassOf(newClass, _statefulWidget)) {
      if (_hasSubClasses(newClass, partialComponent, classHierarchy)) {
        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 (_hasSubClasses(
            statefulWidgetType, partialComponent, classHierarchy)) {
          return null;
        }
        return statefulWidgetType.name;
      }
    }

    return null;
  }

  /// Checks whether the class [node] has any subclasses.
  bool _hasSubClasses(
      Class node, Component component, ClassHierarchy classHierarchy) {
    for (Library library in component.libraries) {
      for (Class otherClass in library.classes) {
        if (identical(otherClass, node)) {
          continue;
        }
        if (classHierarchy.isSubclassOf(otherClass, node)) {
          return true;
        }
      }
    }
    return false;
  }

  // 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;
  }
}
