// Copyright (c) 2016, 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:source_span/source_span.dart';

import 'visitor.dart';

/// The superclass of nodes in the boolean selector abstract syntax tree.
abstract class Node {
  /// The span indicating where this node came from.
  ///
  /// This is a [FileSpan] because the nodes are parsed from a single continuous
  /// string, but the string itself isn't actually a file. It might come from a
  /// statically-parsed annotation or from a parameter.
  ///
  /// This may be `null` for nodes without source information.
  FileSpan get span;

  /// All the variables in this node, in the order they appear.
  Iterable<String> get variables;

  /// Calls the appropriate [Visitor] method on [this] and returns the result.
  dynamic accept(Visitor visitor);
}

/// A single variable.
class VariableNode implements Node {
  @override
  final FileSpan span;

  /// The variable name.
  final String name;

  @override
  Iterable<String> get variables => [name];

  VariableNode(this.name, [this.span]);

  @override
  dynamic accept(Visitor visitor) => visitor.visitVariable(this);

  @override
  String toString() => name;

  @override
  bool operator ==(other) => other is VariableNode && name == other.name;

  @override
  int get hashCode => name.hashCode;
}

/// A negation expression.
class NotNode implements Node {
  @override
  final FileSpan span;

  /// The expression being negated.
  final Node child;

  @override
  Iterable<String> get variables => child.variables;

  NotNode(this.child, [this.span]);

  @override
  dynamic accept(Visitor visitor) => visitor.visitNot(this);

  @override
  String toString() =>
      child is VariableNode || child is NotNode ? '!$child' : '!($child)';

  @override
  bool operator ==(other) => other is NotNode && child == other.child;

  @override
  int get hashCode => ~child.hashCode;
}

/// An or expression.
class OrNode implements Node {
  @override
  FileSpan get span => _expandSafe(left.span, right.span);

  /// The left-hand branch of the expression.
  final Node left;

  /// The right-hand branch of the expression.
  final Node right;

  @override
  Iterable<String> get variables sync* {
    yield* left.variables;
    yield* right.variables;
  }

  OrNode(this.left, this.right);

  @override
  dynamic accept(Visitor visitor) => visitor.visitOr(this);

  @override
  String toString() {
    var string1 = left is AndNode || left is ConditionalNode ? '($left)' : left;
    var string2 =
        right is AndNode || right is ConditionalNode ? '($right)' : right;

    return '$string1 || $string2';
  }

  @override
  bool operator ==(other) =>
      other is OrNode && left == other.left && right == other.right;

  @override
  int get hashCode => left.hashCode ^ right.hashCode;
}

/// An and expression.
class AndNode implements Node {
  @override
  FileSpan get span => _expandSafe(left.span, right.span);

  /// The left-hand branch of the expression.
  final Node left;

  /// The right-hand branch of the expression.
  final Node right;

  @override
  Iterable<String> get variables sync* {
    yield* left.variables;
    yield* right.variables;
  }

  AndNode(this.left, this.right);

  @override
  dynamic accept(Visitor visitor) => visitor.visitAnd(this);

  @override
  String toString() {
    var string1 = left is OrNode || left is ConditionalNode ? '($left)' : left;
    var string2 =
        right is OrNode || right is ConditionalNode ? '($right)' : right;

    return '$string1 && $string2';
  }

  @override
  bool operator ==(other) =>
      other is AndNode && left == other.left && right == other.right;

  @override
  int get hashCode => left.hashCode ^ right.hashCode;
}

/// A ternary conditional expression.
class ConditionalNode implements Node {
  @override
  FileSpan get span => _expandSafe(condition.span, whenFalse.span);

  /// The condition expression to check.
  final Node condition;

  /// The branch to run if the condition is true.
  final Node whenTrue;

  /// The branch to run if the condition is false.
  final Node whenFalse;

  @override
  Iterable<String> get variables sync* {
    yield* condition.variables;
    yield* whenTrue.variables;
    yield* whenFalse.variables;
  }

  ConditionalNode(this.condition, this.whenTrue, this.whenFalse);

  @override
  dynamic accept(Visitor visitor) => visitor.visitConditional(this);

  @override
  String toString() {
    var conditionString =
        condition is ConditionalNode ? '($condition)' : condition;
    var trueString = whenTrue is ConditionalNode ? '($whenTrue)' : whenTrue;
    return '$conditionString ? $trueString : $whenFalse';
  }

  @override
  bool operator ==(other) =>
      other is ConditionalNode &&
      condition == other.condition &&
      whenTrue == other.whenTrue &&
      whenFalse == other.whenFalse;

  @override
  int get hashCode =>
      condition.hashCode ^ whenTrue.hashCode ^ whenFalse.hashCode;
}

/// Like [FileSpan.expand], except if [start] and [end] are `null` or from
/// different files it returns `null` rather than throwing an error.
FileSpan _expandSafe(FileSpan start, FileSpan end) {
  if (start == null || end == null) return null;
  if (start.file != end.file) return null;
  return start.expand(end);
}
