// Copyright (c) 2017, 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:analyzer/analysis_rule/rule_context.dart';
import 'package:analyzer/analysis_rule/rule_visitor_registry.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/error/error.dart';

import '../analyzer.dart';

const _desc = r'Only use double quotes for strings containing single quotes.';

class PreferSingleQuotes extends LintRule {
  PreferSingleQuotes()
    : super(name: LintNames.prefer_single_quotes, description: _desc);

  @override
  DiagnosticCode get diagnosticCode => LinterLintCode.preferSingleQuotes;

  @override
  List<String> get incompatibleRules => const [LintNames.prefer_double_quotes];

  @override
  void registerNodeProcessors(
    RuleVisitorRegistry registry,
    RuleContext context,
  ) {
    var visitor = QuoteVisitor(this, useSingle: true);
    registry.addSimpleStringLiteral(this, visitor);
    registry.addStringInterpolation(this, visitor);
  }
}

class QuoteVisitor extends SimpleAstVisitor<void> {
  final LintRule rule;
  final bool useSingle;

  QuoteVisitor(this.rule, {required this.useSingle});

  /// Strings interpolations can contain other string nodes. Check like this.
  bool containsString(StringInterpolation string) {
    var checkHasString = _IsOrContainsStringVisitor();
    return string.elements.any(
      (child) => child.accept(checkHasString) ?? false,
    );
  }

  /// Strings can be within interpolations (ie, nested). Check like this.
  bool isNestedString(AstNode node) =>
      // careful: node.getAncestor will check the node itself.
      node.parent?.thisOrAncestorOfType<StringInterpolation>() != null;

  @override
  void visitSimpleStringLiteral(SimpleStringLiteral node) {
    if (useSingle && (node.isSingleQuoted || node.value.contains("'")) ||
        !useSingle && (!node.isSingleQuoted || node.value.contains('"'))) {
      return;
    }

    // Bail out on 'strings ${x ? "containing" : "other"} strings'
    if (!isNestedString(node)) {
      rule.reportAtToken(node.literal);
    }
  }

  @override
  void visitStringInterpolation(StringInterpolation node) {
    if (useSingle && node.isSingleQuoted ||
        !useSingle && !node.isSingleQuoted) {
      return;
    }

    // slightly more complicated check there are no single quotes
    if (node.elements.any(
      (e) =>
          e is InterpolationString &&
          (useSingle && e.value.contains("'") ||
              !useSingle && e.value.contains('"')),
    )) {
      return;
    }

    // Bail out on "strings ${x ? 'containing' : 'other'} strings"
    if (!containsString(node) && !isNestedString(node)) {
      rule.reportAtNode(node);
    }
  }
}

/// The only way to get immediate children in a unified, typesafe way, is to
/// call visitChildren on that node, and pass in a visitor. This collects at the
/// top level and stops.
class _ImmediateChildrenVisitor extends UnifyingAstVisitor<void> {
  final _children = <AstNode>[];

  @override
  void visitNode(AstNode node) {
    _children.add(node);
  }

  static List<AstNode> childrenOf(AstNode node) {
    var visitor = _ImmediateChildrenVisitor();
    node.visitChildren(visitor);
    return visitor._children;
  }
}

/// Do a top-down analysis to search for string nodes. Note, do not pass in
/// string nodes directly to this visitor, or you will always get true. Pass in
/// its children.
class _IsOrContainsStringVisitor extends UnifyingAstVisitor<bool> {
  /// Different way to express `accept` in a way that's clearer in this visitor.
  bool isOrContainsString(AstNode node) => node.accept(this) ?? false;

  /// Scan as little of the tree as possible, by bailing out on first match. For
  /// all leaf nodes, they will either have a method defined here and return
  /// true, or they will return false because leaves have no children.
  @override
  bool visitNode(AstNode node) =>
      _ImmediateChildrenVisitor.childrenOf(node).any(isOrContainsString);

  @override
  bool visitSimpleStringLiteral(SimpleStringLiteral string) => true;

  @override
  bool visitStringInterpolation(StringInterpolation string) => true;
}
