// 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 'dart:io';
import 'dart:isolate';

import 'package:args/command_runner.dart';
import 'package:http/http.dart' as http;
import 'package:source_span/source_span.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:yaml/yaml.dart';

import 'dart.dart';
import 'http.dart';
import 'log.dart' as log;
import 'source.dart';

/// An exception class for exceptions that are intended to be seen by the user.
///
/// These exceptions won't have any debugging information printed when they're
/// thrown.
class ApplicationException implements Exception {
  final String message;

  ApplicationException(this.message);

  @override
  String toString() => message;
}

/// A subclass of [ApplicationException] that occurs when running a subprocess
/// has failed.
class RunProcessException extends ApplicationException {
  RunProcessException(super.message);
}

/// An exception class for exceptions that are intended to be seen by the user
/// and are associated with a problem in a file at some path.
class FileException implements ApplicationException {
  @override
  final String message;

  /// The path to the file that was missing or erroneous.
  final String path;

  FileException(this.message, this.path);

  @override
  String toString() => message;
}

/// A class for exceptions that wrap other exceptions.
class WrappedException extends ApplicationException {
  /// The underlying exception that `this` is wrapping, if any.
  final Object? innerError;

  /// The stack chain for [innerError] if it exists.
  final Chain? innerChain;

  WrappedException(super.message, this.innerError, [StackTrace? innerTrace])
      : innerChain = innerTrace == null ? null : Chain.forTrace(innerTrace);
}

/// A class for exceptions that shouldn't be printed at the top level.
///
/// This is usually used when an exception has already been printed using
/// [log.exception].
class SilentException extends WrappedException {
  SilentException(Object? innerError, [StackTrace? innerTrace])
      : super(innerError.toString(), innerError, innerTrace);
}

/// A class for errors in a command's input data.
///
/// This corresponds to the `data` exit code.
class DataException extends ApplicationException {
  DataException(super.message);
}

/// An exception indicating that the users configuration is invalid.
///
/// This corresponds to the `config` exit code;
class ConfigException extends ApplicationException {
  ConfigException(super.message);
}

/// An class for exceptions where a package could not be found in a [Source].
///
/// The source is responsible for wrapping its internal exceptions in this so
/// that other code in pub can use this to show a more detailed explanation of
/// why the package was being requested.
class PackageNotFoundException extends WrappedException {
  /// A hint indicating an action the user could take to resolve this problem.
  ///
  /// This will be printed after the package resolution conflict.
  final String? hint;

  PackageNotFoundException(
    String message, {
    Object? innerError,
    StackTrace? innerTrace,
    this.hint,
  }) : super(message, innerError, innerTrace);

  @override
  String toString() => 'Package not available ($message).';
}

/// A class for exceptions where a package's checksum could not be validated.
class PackageIntegrityException extends PubHttpException {
  PackageIntegrityException(super.message) : super(isIntermittent: true);
}

/// Returns whether [error] is a user-facing error object.
///
/// This includes both [ApplicationException] and any dart:io errors.
bool isUserFacingException(Object error) {
  return error is ApplicationException ||
      error is AnalyzerErrorGroup ||
      error is IsolateSpawnException ||
      error is IOException ||
      error is http.ClientException ||
      error is YamlException ||
      error is UsageException;
}

/// An exception thrown when parsing a `pubspec.yaml` or a `pubspec.lock`.
///
/// These exceptions are often thrown lazily while accessing pubspec properties.
///
/// By being an [ApplicationException] this will not trigger a stack-trace on
/// normal operations.
///
/// Works as a [SourceSpanFormatException], but can contain more context:
/// An optional [explanation] that explains the operation that failed.
/// An optional [hint] that gives suggestions how to proceed.
class SourceSpanApplicationException extends SourceSpanFormatException
    implements ApplicationException {
  final String? explanation;
  final String? hint;

  SourceSpanApplicationException(
    super.message,
    super.span, {
    this.hint,
    this.explanation,
  });

  @override
  String toString({Object? color}) {
    return [
      if (explanation != null) explanation,
      span == null
          ? message
          : 'Error on ${span?.message(message, color: color)}',
      if (hint != null) hint,
    ].join('\n\n');
  }
}
