// Copyright (c) 2019, 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/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/summary2/ast_text_printer.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/ast/parse_base.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AstTextPrinterTest);
    defineReflectiveTests(AstTextPrinterWithUiAsCodeTest);
  });
}

/// Assert that the [code] parsed into AST, when it does not have parse errors,
/// and printed with [AstTextPrinter], gives exactly the same [code].
///
/// Whitespaces and newlines are normalized and ignored.
void assertParseCodeAndPrintAst(ParseBase base, String code,
    {bool mightHasParseErrors: false}) {
  code = code.trimRight();
  code = code.replaceAll('\t', ' ');
  code = code.replaceAll('\r\n', '\n');
  code = code.replaceAll('\r', '\n');

  var path = base.newFile('/home/test/lib/test.dart', content: code).path;

  ParseResult parseResult;
  try {
    parseResult = base.parseUnit(path);
  } catch (e) {
    return;
  }

  // Code with parsing errors cannot be restored.
  if (parseResult.errors.isNotEmpty) {
    if (mightHasParseErrors) return;
    expect(parseResult.errors, isEmpty);
  }

  var buffer = StringBuffer();
  parseResult.unit.accept(
    AstTextPrinter(buffer, parseResult.lineInfo),
  );

//    print('---------------------');
//    print(buffer.toString());
//    print('---------------------');
  expect(buffer.toString(), code);
}

@reflectiveTest
class AstTextPrinterTest extends ParseBase {
  test_commentOnly() async {
    assertParseCodeAndPrintAst(this, r'''
// aaa
// bbb
''');
  }

  test_simple() async {
    assertParseCodeAndPrintAst(this, r'''
class C {
  void foo() {
    1;
    2 + 3;
  }
}
''');
  }

  test_spaces_emptyLine() async {
    assertParseCodeAndPrintAst(this, '''
class A {}
${' ' * 2}
class B {}
''');
  }
}

@reflectiveTest
class AstTextPrinterWithUiAsCodeTest extends ParseBase {
  @override
  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
    ..enabledExperiments = [
      EnableString.control_flow_collections,
      EnableString.spread_collections,
    ];

  test_forElement() async {
    assertParseCodeAndPrintAst(this, r'''
var _ = [1, for (var v in [2, 3, 4]) v, 5];
''');
  }

  test_ifElement_then() async {
    assertParseCodeAndPrintAst(this, r'''
var _ = [1, if (true) 2, 3];
''');
  }

  test_ifElement_thenElse() async {
    assertParseCodeAndPrintAst(this, r'''
var _ = [1, if (true) 2 else 3, 4];
''');
  }

  test_spreadElement() async {
    assertParseCodeAndPrintAst(this, r'''
var _ = [1, ...[2, 3], 4];
''');
  }

  test_spreadElement_nullable() async {
    assertParseCodeAndPrintAst(this, r'''
var _ = [1, ...?[2, 3], 4];
''');
  }
}
