// Copyright 2014 The Flutter Authors. 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:html' as html;

import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:meta/dart2js.dart';

/// Expected sequence of method calls.
const List<String> callChain = <String>['baz', 'bar', 'foo'];

final List<StackFrame> expectedProfileStackFrames = callChain.map<StackFrame>((String method) {
  return StackFrame(
    number: -1,
    packageScheme: '<unknown>',
    package: '<unknown>',
    packagePath: '<unknown>',
    line: -1,
    column: -1,
    className: 'Object',
    method: method,
    source: '',
  );
}).toList();

// TODO(yjbanov): fix these stack traces when https://github.com/flutter/flutter/issues/50753 is fixed.
const List<StackFrame> expectedDebugStackFrames = <StackFrame>[
  StackFrame(
    number: -1,
    packageScheme: 'package',
    package: 'packages',
    packagePath: 'web_integration/stack_trace.dart',
    line: 119,
    column: 3,
    className: '<unknown>',
    method: 'baz',
    source: '',
  ),
  StackFrame(
    number: -1,
    packageScheme: 'package',
    package: 'packages',
    packagePath: 'web_integration/stack_trace.dart',
    line: 114,
    column: 3,
    className: '<unknown>',
    method: 'bar',
    source: '',
  ),
  StackFrame(
    number: -1,
    packageScheme: 'package',
    package: 'packages',
    packagePath: 'web_integration/stack_trace.dart',
    line: 109,
    column: 3,
    className: '<unknown>',
    method: 'foo',
    source: '',
  ),
];

/// Tests that we do not crash while parsing Web stack traces.
///
/// This test is run in debug, profile, and release modes.
void main() {
  final StringBuffer output = StringBuffer();
  try {
    try {
      foo();
    } catch (expectedError, expectedStackTrace) {
      final List<StackFrame> parsedFrames = StackFrame.fromStackTrace(expectedStackTrace);
      if (parsedFrames.isEmpty) {
        throw Exception(
          'Failed to parse stack trace. Got empty list of stack frames.\n'
          'Stack trace:\n$expectedStackTrace'
        );
      }

      // Symbols in release mode are randomly obfuscated, so there's no good way to
      // validate the contents. However, profile mode can be checked.
      if (kProfileMode) {
        _checkStackFrameContents(parsedFrames, expectedProfileStackFrames, expectedStackTrace);
      }

      if (kDebugMode) {
        _checkStackFrameContents(parsedFrames, expectedDebugStackFrames, expectedStackTrace);
      }
    }
    output.writeln('--- TEST SUCCEEDED ---');
  } catch (unexpectedError, unexpectedStackTrace) {
    output.writeln('--- UNEXPECTED EXCEPTION ---');
    output.writeln(unexpectedError);
    output.writeln(unexpectedStackTrace);
    output.writeln('--- TEST FAILED ---');
  }
  print(output);
  html.HttpRequest.request(
    '/test-result',
    method: 'POST',
    sendData: '$output',
  );
}

@noInline
void foo() {
  bar();
}

@noInline
void bar() {
  baz();
}

@noInline
void baz() {
  throw Exception('Test error message');
}

void _checkStackFrameContents(List<StackFrame> parsedFrames, List<StackFrame> expectedFrames, dynamic stackTrace) {
  // Filter out stack frames outside this library so this test is less brittle.
  final List<StackFrame> actual = parsedFrames
    .where((StackFrame frame) => callChain.contains(frame.method))
    .toList();
  final bool stackFramesAsExpected = ListEquality<StackFrame>(StackFrameEquality()).equals(actual, expectedFrames);
  if (!stackFramesAsExpected) {
    throw Exception(
      'Stack frames parsed incorrectly:\n'
      'Expected:\n${expectedFrames.join('\n')}\n'
      'Actual:\n${actual.join('\n')}\n'
      'Stack trace:\n$stackTrace'
    );
  }
}

/// Use custom equality to ignore [StackFrame.source], which is not important
/// for the purposes of this test.
class StackFrameEquality implements Equality<StackFrame> {
  @override
  bool equals(StackFrame e1, StackFrame e2) {
    return e1.number == e2.number &&
           e1.packageScheme == e2.packageScheme &&
           e1.package == e2.package &&
           e1.packagePath == e2.packagePath &&
           e1.line == e2.line &&
           e1.column == e2.column &&
           e1.className == e2.className &&
           e1.method == e2.method;
  }

  @override
  int hash(StackFrame e) {
    return Object.hash(e.number, e.packageScheme, e.package, e.packagePath, e.line, e.column, e.className, e.method);
  }

  @override
  bool isValidKey(Object? o) => o is StackFrame;
}
