// Copyright (c) 2014, 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_plugin/protocol/protocol_common.dart';

/// An outcome of a condition checking operation.
class RefactoringStatus {
  /// The current severity of this [RefactoringStatus] - the maximum of the
  /// severities of its [entries].
  RefactoringProblemSeverity _severity;

  /// A list of [RefactoringProblem]s.
  final List<RefactoringProblem> problems = [];

  /// Creates a new OK [RefactoringStatus].
  RefactoringStatus();

  /// Creates a new [RefactoringStatus] with the ERROR severity.
  factory RefactoringStatus.error(String msg, [Location location]) {
    var status = RefactoringStatus();
    status.addError(msg, location);
    return status;
  }

  /// Creates a new [RefactoringStatus] with the FATAL severity.
  factory RefactoringStatus.fatal(String msg, [Location location]) {
    var status = RefactoringStatus();
    status.addFatalError(msg, location);
    return status;
  }

  /// Creates a new [RefactoringStatus] with the WARNING severity.
  factory RefactoringStatus.warning(String msg, [Location location]) {
    var status = RefactoringStatus();
    status.addWarning(msg, location);
    return status;
  }

  /// Returns `true` if the severity is FATAL or ERROR.
  bool get hasError {
    return _severity == RefactoringProblemSeverity.FATAL ||
        _severity == RefactoringProblemSeverity.ERROR;
  }

  /// Returns `true` if the severity is FATAL.
  bool get hasFatalError => _severity == RefactoringProblemSeverity.FATAL;

  /// Returns `true` if the severity is WARNING.
  bool get hasWarning => _severity == RefactoringProblemSeverity.WARNING;

  /// Return `true` if the severity is `OK`.
  bool get isOK => _severity == null;

  /// Returns the message of the [RefactoringProblem] with highest severity;
  /// may be `null` if no problems.
  String get message {
    var problem = this.problem;
    if (problem == null) {
      return null;
    }
    return problem.message;
  }

  /// Returns the first [RefactoringProblem] with the highest severity.
  ///
  /// Returns `null` if no entries.
  RefactoringProblem get problem {
    for (var problem in problems) {
      if (problem.severity == _severity) {
        return problem;
      }
    }
    return null;
  }

  /// Returns the current severity of this [RefactoringStatus].
  RefactoringProblemSeverity get severity => _severity;

  /// Adds an ERROR problem with the given message and location.
  void addError(String msg, [Location location]) {
    _addProblem(RefactoringProblem(RefactoringProblemSeverity.ERROR, msg,
        location: location));
  }

  /// Adds a FATAL problem with the given message and location.
  void addFatalError(String msg, [Location location]) {
    _addProblem(RefactoringProblem(RefactoringProblemSeverity.FATAL, msg,
        location: location));
  }

  /// Merges [other] into this [RefactoringStatus].
  ///
  /// The [other]'s entries are added to this.
  ///
  /// The resulting severity is the more severe of this and [other] severities.
  ///
  /// Merging with `null` is allowed - it has no effect.
  void addStatus(RefactoringStatus other) {
    if (other == null) {
      return;
    }
    problems.addAll(other.problems);
    _severity = RefactoringProblemSeverity.max(_severity, other.severity);
  }

  /// Adds a WARNING problem with the given message and location.
  void addWarning(String msg, [Location location]) {
    _addProblem(RefactoringProblem(RefactoringProblemSeverity.WARNING, msg,
        location: location));
  }

  @override
  String toString() {
    var sb = StringBuffer();
    sb.write('<');
    if (_severity == null) {
      sb.write('OK');
    } else {
      sb.write(_severity.name);
    }
    if (!isOK) {
      sb.write('\n');
      for (var problem in problems) {
        sb.write('\t');
        sb.write(problem);
        sb.write('\n');
      }
    }
    sb.write('>');
    return sb.toString();
  }

  /// Adds the given [RefactoringProblem] and updates [severity].
  void _addProblem(RefactoringProblem problem) {
    problems.add(problem);
    // update maximum severity
    var severity = problem.severity;
    _severity = RefactoringProblemSeverity.max(_severity, severity);
  }
}
