// Copyright (c) 2022, 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:analysis_server/src/services/snippets/dart/dart_snippet_producers.dart';
import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:meta/meta.dart';

abstract class FlutterSnippetProducer extends DartSnippetProducer {
  final flutter = Flutter.instance;

  late ClassElement? classWidget;

  FlutterSnippetProducer(DartSnippetRequest request) : super(request);

  @override
  @mustCallSuper
  Future<bool> isValid() async {
    if ((classWidget = await _getClass('Widget')) == null) {
      return false;
    }

    return super.isValid();
  }

  Future<ClassElement?> _getClass(String name) =>
      sessionHelper.getClass(flutter.widgetsUri, name);

  DartType _getType(
    ClassElement classElement, [
    NullabilitySuffix nullabilitySuffix = NullabilitySuffix.none,
  ]) =>
      classElement.instantiate(
        typeArguments: const [],
        nullabilitySuffix: nullabilitySuffix,
      );
}

/// Produces a [Snippet] that creates a Flutter StatefulWidget and related State
/// class.
class FlutterStatefulWidgetSnippetProducer extends FlutterSnippetProducer
    with FlutterWidgetSnippetProducerMixin {
  static const prefix = 'stful';
  static const label = 'Flutter Stateful Widget';

  late ClassElement? classStatefulWidget;
  late ClassElement? classState;
  @override
  late ClassElement? classBuildContext;
  @override
  late ClassElement? classKey;

  FlutterStatefulWidgetSnippetProducer._(DartSnippetRequest request)
      : super(request);

  @override
  Future<Snippet> compute() async {
    final builder = ChangeBuilder(session: request.analysisSession);

    // Checked by isValid().
    final classStatefulWidget = this.classStatefulWidget!;
    final classState = this.classState!;

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        // Write the StatefulWidget class
        builder.writeClassDeclaration(
          widgetClassName,
          nameGroupName: 'name',
          superclass: _getType(classStatefulWidget),
          membersWriter: () {
            writeWidgetConstructor(builder);
            builder.writeln();
            builder.writeln();

            writeCreateStateMethod(builder);
          },
        );
        builder.writeln();
        builder.writeln();

        // Write the State class.
        builder.write('class _');
        builder.addSimpleLinkedEdit('name', widgetClassName);
        builder.write('State extends ');
        builder.writeReference(classState);
        builder.write('<');
        builder.addSimpleLinkedEdit('name', widgetClassName);
        builder.writeln('> {');
        {
          writeBuildMethod(builder);
        }
        builder.write('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a Flutter StatefulWidget.',
      builder.sourceChange,
    );
  }

  @override
  Future<bool> isValid() async {
    if (!await super.isValid()) {
      return false;
    }

    if ((classStatefulWidget = await _getClass('StatefulWidget')) == null ||
        (classState = await _getClass('State')) == null ||
        (classBuildContext = await _getClass('BuildContext')) == null ||
        (classKey = await _getClass('Key')) == null) {
      return false;
    }

    return true;
  }

  static FlutterStatefulWidgetSnippetProducer newInstance(
          DartSnippetRequest request) =>
      FlutterStatefulWidgetSnippetProducer._(request);
}

/// Produces a [Snippet] that creates a Flutter StatefulWidget with a
/// AnimationController and related State class.
class FlutterStatefulWidgetWithAnimationControllerSnippetProducer
    extends FlutterSnippetProducer with FlutterWidgetSnippetProducerMixin {
  static const prefix = 'stanim';
  static const label = 'Flutter Widget with AnimationController';

  late ClassElement? classStatefulWidget;
  late ClassElement? classState;
  @override
  late ClassElement? classBuildContext;
  @override
  late ClassElement? classKey;
  late ClassElement? classAnimationController;
  late ClassElement? classSingleTickerProviderStateMixin;

  FlutterStatefulWidgetWithAnimationControllerSnippetProducer._(
      DartSnippetRequest request)
      : super(request);

  @override
  Future<Snippet> compute() async {
    final builder = ChangeBuilder(session: request.analysisSession);

    // Checked by isValid().
    final classStatefulWidget = this.classStatefulWidget!;
    final classState = this.classState!;
    final classAnimationController = this.classAnimationController!;
    final classSingleTickerProviderStateMixin =
        this.classSingleTickerProviderStateMixin!;

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        // Write the StatefulWidget class
        builder.writeClassDeclaration(
          widgetClassName,
          nameGroupName: 'name',
          superclass: _getType(classStatefulWidget),
          membersWriter: () {
            writeWidgetConstructor(builder);
            builder.writeln();
            builder.writeln();

            writeCreateStateMethod(builder);
          },
        );
        builder.writeln();
        builder.writeln();

        // Write the State class.
        builder.write('class _');
        builder.addSimpleLinkedEdit('name', widgetClassName);
        builder.write('State extends ');
        builder.writeReference(classState);
        builder.write('<');
        builder.addSimpleLinkedEdit('name', widgetClassName);
        builder.writeln('>');
        builder.write('    with ');
        builder.writeReference(classSingleTickerProviderStateMixin);
        builder.writeln(' {');
        builder.write('  late ');
        builder.writeReference(classAnimationController);
        builder.writeln(' _controller;');
        builder.writeln();
        {
          // Add the initState method.
          builder.writeln('  @override');
          builder.write('  ');
          builder.writeFunctionDeclaration(
            'initState',
            returnType: VoidTypeImpl.instance,
            bodyWriter: () {
              builder.writeln('{');
              builder.writeln('    super.initState();');
              builder.write('    _controller = ');
              builder.writeReference(classAnimationController);
              builder.writeln('(vsync: this);');
              builder.writeln('  }');
            },
          );
        }
        builder.writeln();
        {
          // Add the dispose method.
          builder.writeln('  @override');
          builder.write('  ');
          builder.writeFunctionDeclaration(
            'dispose',
            returnType: VoidTypeImpl.instance,
            bodyWriter: () {
              builder.writeln('{');
              builder.writeln('    super.dispose();');
              builder.writeln('    _controller.dispose();');
              builder.writeln('  }');
            },
          );
        }
        builder.writeln();
        {
          writeBuildMethod(builder);
        }
        builder.write('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a Flutter StatefulWidget with an AnimationController.',
      builder.sourceChange,
    );
  }

  @override
  Future<bool> isValid() async {
    if (!await super.isValid()) {
      return false;
    }

    if ((classStatefulWidget = await _getClass('StatefulWidget')) == null ||
        (classState = await _getClass('State')) == null ||
        (classBuildContext = await _getClass('BuildContext')) == null ||
        (classKey = await _getClass('Key')) == null ||
        (classAnimationController = await _getClass('AnimationController')) ==
            null ||
        (classSingleTickerProviderStateMixin =
                await _getClass('SingleTickerProviderStateMixin')) ==
            null) {
      return false;
    }

    return true;
  }

  static FlutterStatefulWidgetWithAnimationControllerSnippetProducer
      newInstance(DartSnippetRequest request) =>
          FlutterStatefulWidgetWithAnimationControllerSnippetProducer._(
              request);
}

/// Produces a [Snippet] that creates a Flutter StatelessWidget.
class FlutterStatelessWidgetSnippetProducer extends FlutterSnippetProducer
    with FlutterWidgetSnippetProducerMixin {
  static const prefix = 'stless';
  static const label = 'Flutter Stateless Widget';

  late ClassElement? classStatelessWidget;
  @override
  late ClassElement? classBuildContext;
  @override
  late ClassElement? classKey;

  FlutterStatelessWidgetSnippetProducer._(DartSnippetRequest request)
      : super(request);

  @override
  Future<Snippet> compute() async {
    final builder = ChangeBuilder(session: request.analysisSession);

    // Checked by isValid().
    final classStatelessWidget = this.classStatelessWidget!;

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        builder.writeClassDeclaration(
          widgetClassName,
          nameGroupName: 'name',
          superclass: _getType(classStatelessWidget),
          membersWriter: () {
            writeWidgetConstructor(builder);
            builder.writeln();
            builder.writeln();

            writeBuildMethod(builder);
          },
        );
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a Flutter StatelessWidget.',
      builder.sourceChange,
    );
  }

  @override
  Future<bool> isValid() async {
    if (!await super.isValid()) {
      return false;
    }

    if ((classStatelessWidget = await _getClass('StatelessWidget')) == null ||
        (classBuildContext = await _getClass('BuildContext')) == null ||
        (classKey = await _getClass('Key')) == null) {
      return false;
    }

    return true;
  }

  static FlutterStatelessWidgetSnippetProducer newInstance(
          DartSnippetRequest request) =>
      FlutterStatelessWidgetSnippetProducer._(request);
}

/// A mixin that provides some common methods for producers that build snippets
/// for Flutter widget classes.
mixin FlutterWidgetSnippetProducerMixin on FlutterSnippetProducer {
  ClassElement? get classBuildContext;
  ClassElement? get classKey;
  String get widgetClassName => 'MyWidget';

  void writeBuildMethod(DartEditBuilder builder) {
    // Checked by isValid() before this will be called.
    final classBuildContext = this.classBuildContext!;
    final classWidget = this.classWidget!;

    // Add the build method.
    builder.writeln('  @override');
    builder.write('  ');
    builder.writeFunctionDeclaration(
      'build',
      returnType: _getType(classWidget),
      parameterWriter: () {
        builder.writeParameter(
          'context',
          type: _getType(classBuildContext),
        );
      },
      bodyWriter: () {
        builder.writeln('{');
        builder.write('    ');
        builder.selectHere();
        builder.writeln();
        builder.writeln('  }');
      },
    );
  }

  void writeCreateStateMethod(DartEditBuilder builder) {
    builder.writeln('  @override');
    builder.write('  State<');
    builder.addSimpleLinkedEdit('name', widgetClassName);
    builder.write('> createState() => _');
    builder.addSimpleLinkedEdit('name', widgetClassName);
    builder.writeln('State();');
  }

  void writeWidgetConstructor(DartEditBuilder builder) {
    // Checked by isValid() before this will be called.
    final classKey = this.classKey!;

    String keyName;
    DartType? keyType;
    void Function()? keyInitializer;
    if (useSuperParams) {
      keyName = 'super.key';
    } else {
      keyName = 'key';
      keyType = _getType(classKey, nullableSuffix);
      keyInitializer = () => builder.write('super(key: key)');
    }

    builder.write('  ');
    builder.writeConstructorDeclaration(
      widgetClassName,
      classNameGroupName: 'name',
      isConst: true,
      parameterWriter: () {
        builder.write('{');
        builder.writeParameter(keyName, type: keyType);
        builder.write('}');
      },
      initializerWriter: keyInitializer,
    );
  }
}
