// Copyright (c) 2018, 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:convert';

import 'package:checked_yaml/checked_yaml.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:test/test.dart';

import 'pub_utils.dart';

const defaultPubspec = {
  'name': 'sample',
  'environment': {'sdk': '>=2.12.0 <3.0.0'},
};

String _encodeJson(Object? input) =>
    const JsonEncoder.withIndent(' ').convert(input);

Matcher _throwsParsedYamlException(String prettyValue) => throwsA(
  const TypeMatcher<ParsedYamlException>().having(
    (e) {
      final message = e.formattedMessage;
      printOnFailure("Actual error format:\nr'''\n$message'''");
      _printDebugParsedYamlException(e);
      return message;
    },
    'formattedMessage',
    prettyValue,
  ),
);

void _printDebugParsedYamlException(ParsedYamlException e) {
  var innerError = e.innerError;
  StackTrace? innerStack;

  if (innerError is CheckedFromJsonException) {
    final cfje = innerError;

    if (cfje.innerError != null) {
      innerError = cfje.innerError;
      innerStack = cfje.innerStack;
    }
  }

  if (innerError != null) {
    final items = [innerError];
    if (innerStack != null) {
      items.add(Trace.format(innerStack));
    }

    final content = LineSplitter.split(
      items.join('\n'),
    ).map((e) => '  $e').join('\n');

    printOnFailure('Inner error details:\n$content');
  }
}

Future<Pubspec> parse(
  Object? content, {
  bool quietOnError = false,
  bool skipTryPub = false,
  bool lenient = false,
}) async {
  final encoded = _encodeJson(content);

  ProcResult? pubResult;
  if (!skipTryPub) {
    // ignore: deprecated_member_use
    pubResult = await tryPub(encoded);
    expect(pubResult, isNotNull);
  }

  try {
    final value = Pubspec.parse(encoded, lenient: lenient);

    if (pubResult != null) {
      addTearDown(() {
        expect(
          pubResult!.cleanParse,
          isTrue,
          reason:
              'On success, parsing from the pub client should also succeed.',
        );
      });
    }
    return value;
  } catch (e) {
    if (pubResult != null) {
      addTearDown(() {
        expect(
          pubResult!.cleanParse,
          isFalse,
          reason: 'On failure, parsing from the pub client should also fail.',
        );
      });
    }
    if (e is ParsedYamlException) {
      if (!quietOnError) {
        _printDebugParsedYamlException(e);
      }
    }
    rethrow;
  }
}

void expectParseThrows(
  Object? content,
  String expectedError, {
  bool skipTryPub = false,
  bool lenient = false,
}) => expect(
  () => parse(
    content,
    lenient: lenient,
    quietOnError: true,
    skipTryPub: skipTryPub,
  ),
  _throwsParsedYamlException(expectedError),
);

void expectParseThrowsContaining(
  Object? content,
  String errorFragment, {
  bool skipTryPub = false,
  bool lenient = false,
}) {
  expect(
    () => parse(
      content,
      lenient: lenient,
      quietOnError: true,
      skipTryPub: skipTryPub,
    ),
    _throwsParsedYamlExceptionContaining(errorFragment),
  );
}

// ignore: prefer_expression_function_bodies
Matcher _throwsParsedYamlExceptionContaining(String errorFragment) {
  return throwsA(
    const TypeMatcher<ParsedYamlException>().having(
      (e) {
        final message = e.formattedMessage;
        printOnFailure("Actual error format:\nr'''\n$message'''");
        _printDebugParsedYamlException(e);
        return message;
      },
      'formattedMessage',
      contains(errorFragment),
    ),
  );
}
