// 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/correction/util.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/snippets/dart/snippet_manager.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/lint/linter.dart' show LinterContextImpl;
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';

/// Produces a [Snippet] that creates a Class definition.
class DartClassSnippetProducer extends DartSnippetProducer {
  static const prefix = 'class';
  static const label = 'class';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write('class ');
        builder.addSimpleLinkedEdit('className', 'ClassName');
        builder.writeln(' {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a class definition.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a `do while` loop.
class DartDoWhileLoopSnippetProducer extends DartSnippetProducer {
  static const prefix = 'do';
  static const label = 'do while';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.writeln('do {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('} while (');
        builder.addSimpleLinkedEdit('condition', 'condition');
        builder.write(');');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a do-while loop.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a `for in` loop.
class DartForInLoopSnippetProducer extends DartSnippetProducer {
  static const prefix = 'forin';
  static const label = 'for in';

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

  @override
  Future<Snippet> compute() async {
    final builder = ChangeBuilder(session: request.analysisSession);
    final indent = utils.getLinePrefix(request.offset);
    final varOrFinal =
        isLintEnabled(LintNames.prefer_final_locals) ? 'final' : 'var';

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write('for ($varOrFinal ');
        builder.addSimpleLinkedEdit('elementName', 'element');
        builder.write(' in ');
        builder.addSimpleLinkedEdit('collectionName', 'collection');
        builder.writeln(') {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a for-in loop.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a `for` loop.
class DartForLoopSnippetProducer extends DartSnippetProducer {
  static const prefix = 'for';
  static const label = 'for';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write('for (var i = 0; i < ');
        builder.addSimpleLinkedEdit('count', 'count');
        builder.writeln('; i++) {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a for loop.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates an if/else statement.
class DartIfElseSnippetProducer extends DartSnippetProducer {
  static const prefix = 'ife';
  static const label = 'ife';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        void writeIndentedln(String string) =>
            builder.writeln('$indent$string');
        builder.write('if (');
        builder.addSimpleLinkedEdit('condition', 'condition');
        builder.writeln(') {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndentedln('} else {');
        writeIndentedln('  ');
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert an if/else statement.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates an if statement.
class DartIfSnippetProducer extends DartSnippetProducer {
  static const prefix = 'if';
  static const label = 'if';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write('if (');
        builder.addSimpleLinkedEdit('condition', 'condition');
        builder.writeln(') {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert an if statement.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a top-level `main` function.
///
/// A `List<String> args` parameter will be included when generating inside a
/// file in `bin` or `tool` folders.
class DartMainFunctionSnippetProducer extends DartSnippetProducer {
  static const prefix = 'main';
  static const label = 'main()';

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

  /// Whether to insert a `List<String> args` parameter in the generated
  /// function.
  ///
  /// The parameter is suppressed for any known test directories.
  bool get _insertArgsParameter => !isInTestDirectory;

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

    final typeProvider = request.unit.typeProvider;
    final listString = typeProvider.listType(typeProvider.stringType);

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        builder.writeFunctionDeclaration(
          'main',
          returnType: VoidTypeImpl.instance,
          parameterWriter: _insertArgsParameter
              ? () => builder.writeParameter('args', type: listString)
              : null,
          bodyWriter: () {
            builder.writeln('{');
            builder.write('  ');
            builder.selectHere();
            builder.writeln();
            builder.write('}');
          },
        );
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a main function, used as an entry point.',
      builder.sourceChange,
    );
  }

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

abstract class DartSnippetProducer extends SnippetProducer {
  final AnalysisSessionHelper sessionHelper;
  final CorrectionUtils utils;

  DartSnippetProducer(DartSnippetRequest request)
      : sessionHelper = AnalysisSessionHelper(request.analysisSession),
        utils = CorrectionUtils(request.unit),
        super(request);

  bool get isInTestDirectory {
    final path = request.unit.path;
    return LinterContextImpl.testDirectories
        .any((testDir) => path.contains(testDir));
  }

  bool isLintEnabled(String name) {
    var analysisOptions = sessionHelper.session.analysisContext.analysisOptions;
    return analysisOptions.isLintEnabled(name);
  }
}

/// Produces a [Snippet] that creates an if statement.
class DartSwitchSnippetProducer extends DartSnippetProducer {
  static const prefix = 'switch';
  static const label = 'switch case';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        void writeIndentedln(String string) =>
            builder.writeln('$indent$string');
        builder.write('switch (');
        builder.addSimpleLinkedEdit('expression', 'expression');
        builder.writeln(') {');
        writeIndented('  case ');
        builder.addSimpleLinkedEdit('value', 'value');
        builder.writeln(':');
        writeIndented('    ');
        builder.selectHere();
        builder.writeln();
        writeIndentedln('    break;');
        writeIndentedln('  default:');
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a switch statement.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a `test()` block.
class DartTestBlockSnippetProducer extends DartSnippetProducer {
  static const prefix = 'test';
  static const label = 'test';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write("test('");
        builder.addSimpleLinkedEdit('testName', 'test name');
        builder.writeln("', () {");
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('});');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a test block.',
      builder.sourceChange,
    );
  }

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

    return isInTestDirectory;
  }

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

/// Produces a [Snippet] that creates a `test()` block.
class DartTestGroupBlockSnippetProducer extends DartSnippetProducer {
  static const prefix = 'group';
  static const label = 'group';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write("group('");
        builder.addSimpleLinkedEdit('groupName', 'group name');
        builder.writeln("', () {");
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('});');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a test group block.',
      builder.sourceChange,
    );
  }

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

    return isInTestDirectory;
  }

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

/// Produces a [Snippet] that creates a try/catch statement.
class DartTryCatchSnippetProducer extends DartSnippetProducer {
  static const prefix = 'try';
  static const label = 'try';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        void writeIndentedln(String string) =>
            builder.writeln('$indent$string');
        builder.writeln('try {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('} catch (');
        builder.addLinkedEdit('exceptionName', (builder) {
          builder.write('e');
        });
        builder.writeln(') {');
        writeIndentedln('  ');
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a try/catch statement.',
      builder.sourceChange,
    );
  }

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

/// Produces a [Snippet] that creates a `while` loop.
class DartWhileLoopSnippetProducer extends DartSnippetProducer {
  static const prefix = 'while';
  static const label = 'while';

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

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

    await builder.addDartFileEdit(request.filePath, (builder) {
      builder.addReplacement(request.replacementRange, (builder) {
        void writeIndented(String string) => builder.write('$indent$string');
        builder.write('while (');
        builder.addSimpleLinkedEdit('condition', 'condition');
        builder.writeln(') {');
        writeIndented('  ');
        builder.selectHere();
        builder.writeln();
        writeIndented('}');
      });
    });

    return Snippet(
      prefix,
      label,
      'Insert a while loop.',
      builder.sourceChange,
    );
  }

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