// 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:async';

import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../abstract_context.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(FlutterOutlineComputerTest);
  });
}

@reflectiveTest
class FlutterOutlineComputerTest extends AbstractContextTest {
  String testPath;
  String testCode;
  AnalysisResult analysisResult;
  FlutterOutlineComputer computer;

  @override
  void setUp() {
    super.setUp();
    testPath = resourceProvider.convertPath('/test.dart');
    addFlutterPackage();
  }

  test_attribute_namedExpression() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

main() {
  return new WidgetA(
    value: 42,
  ); // WidgetA
}

class WidgetA extends StatelessWidget {
  WidgetA({int value});
}
''');
    var main = unitOutline.children[0];
    var widget = main.children[0];
    expect(widget.attributes, hasLength(1));

    var attribute = widget.attributes[0];
    expect(attribute.name, 'value');
    expect(attribute.label, '42');
  }

  test_attributes_bool() async {
    var attribute = await _getAttribute('test', 'true');
    expect(attribute.label, 'true');
    expect(attribute.literalValueBoolean, true);
  }

  test_attributes_functionExpression_hasParameters_blockExpression() async {
    var attribute = await _getAttribute('test', '(a) {}');
    expect(attribute.label, '(…) { … }');
  }

  test_attributes_functionExpression_hasParameters_bodyExpression() async {
    var attribute = await _getAttribute('test', '(a) => 1');
    expect(attribute.label, '(…) => …');
  }

  test_attributes_functionExpression_noParameters_blockExpression() async {
    var attribute = await _getAttribute('test', '() {}');
    expect(attribute.label, '() { … }');
  }

  test_attributes_functionExpression_noParameters_bodyExpression() async {
    var attribute = await _getAttribute('test', '() => 1');
    expect(attribute.label, '() => …');
  }

  test_attributes_int() async {
    var attribute = await _getAttribute('test', '42');
    expect(attribute.label, '42');
    expect(attribute.literalValueInteger, 42);
  }

  test_attributes_listLiteral() async {
    var attribute = await _getAttribute('test', '[1, 2, 3]');
    expect(attribute.label, '[…]');
  }

  test_attributes_mapLiteral() async {
    var attribute = await _getAttribute('test', '{1: 10, 2: 20}');
    expect(attribute.label, '{…}');
  }

  test_attributes_multiLine() async {
    var attribute = await _getAttribute('test', '1 +\n 2');
    expect(attribute.label, '…');
  }

  test_attributes_string_interpolation() async {
    FlutterOutline unitOutline = await _computeOutline(r'''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var name = 'Foo';
    return const Text('Hello, $name!')
  }
}
''');
    var myWidget = unitOutline.children[0];
    var build = myWidget.children[0];
    var textOutline = build.children[0];

    expect(textOutline.attributes, hasLength(1));

    FlutterOutlineAttribute attribute = textOutline.attributes[0];
    expect(attribute.name, 'data');
    expect(attribute.label, r"'Hello, $name!'");
    expect(attribute.literalValueString, isNull);
  }

  test_attributes_string_literal() async {
    var attribute = await _getAttribute('test', "'my text'");
    expect(attribute.label, "'my text'");
    expect(attribute.literalValueString, 'my text');
  }

  test_attributes_unresolved() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const Row(1, foo: 2)
  }
}
''');
    var myWidget = unitOutline.children[0];
    var build = myWidget.children[0];

    var rowOutline = build.children[0];
    expect(rowOutline.attributes, isEmpty);
  }

  test_children() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Column(children: [
      const Text('aaa'),
      const Text('bbb'),
    ]); // Column
  }
}
''');

    expect(_toText(unitOutline), r'''
(D) MyWidget
  (D) build
    Column
      Text
      Text
''');
    var myWidget = unitOutline.children[0];
    var build = myWidget.children[0];

    var columnOutline = build.children[0];
    {
      int offset = testCode.indexOf('new Column');
      int length = testCode.indexOf('; // Column') - offset;
      expect(columnOutline.offset, offset);
      expect(columnOutline.length, length);
    }

    {
      var textOutline = columnOutline.children[0];
      String text = "const Text('aaa')";
      int offset = testCode.indexOf(text);
      expect(textOutline.offset, offset);
      expect(textOutline.length, text.length);
    }

    {
      var textOutline = columnOutline.children[1];
      String text = "const Text('bbb')";
      int offset = testCode.indexOf(text);
      expect(textOutline.offset, offset);
      expect(textOutline.length, text.length);
    }
  }

  test_codeOffsetLength() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

/// Comment
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.offset, 40);
    expect(myWidget.length, 137);
    expect(myWidget.codeOffset, 52);
    expect(myWidget.codeLength, 125);

    var build = myWidget.children[0];
    expect(build.offset, 95);
    expect(build.length, 80);
    expect(build.codeOffset, 107);
    expect(build.codeLength, 68);

    var container = build.children[0];
    expect(container.offset, 155);
    expect(container.length, 15);
    expect(container.codeOffset, 155);
    expect(container.codeLength, 15);
  }

  test_genericLabel_invocation() async {
    FlutterOutline unitOutline = await _computeOutline(r'''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row(children: [
      createText(0),
      createEmptyText(),
      WidgetFactory.createMyText(),
    ]);
  }
  Text createEmptyText() {
    return new Text('');
  }
  Text createText(int index) {
    return new Text('index: $index');
  }
}

class WidgetFactory {
  static Text createMyText() => new Text('');
}
''');
    var myWidget = unitOutline.children[0];
    var build = myWidget.children[0];
    expect(build.children, hasLength(1));

    var row = build.children[0];
    expect(row.kind, FlutterOutlineKind.NEW_INSTANCE);
    expect(row.className, 'Row');
    expect(row.children, hasLength(3));

    {
      var text = row.children[0];
      expect(text.kind, FlutterOutlineKind.GENERIC);
      expect(text.className, 'Text');
      expect(text.label, 'createText(…)');
    }

    {
      var text = row.children[1];
      expect(text.kind, FlutterOutlineKind.GENERIC);
      expect(text.className, 'Text');
      expect(text.label, 'createEmptyText()');
    }

    {
      var text = row.children[2];
      expect(text.kind, FlutterOutlineKind.GENERIC);
      expect(text.className, 'Text');
      expect(text.label, 'WidgetFactory.createMyText()');
    }
  }

  test_parentAssociationLabel() async {
    newFile('/a.dart', content: r'''
import 'package:flutter/widgets.dart';

class WidgetA extends StatelessWidget {
  final Widget top;
  final Widget bottom;
  
  WidgetA({this.top, this.bottom});
}
''');
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';
import 'a.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new WidgetA(
      top: const Text('aaa'),
      bottom: const Text('bbb'),
    ); // WidgetA
  }
}
''');
    expect(_toText(unitOutline), r'''
(D) MyWidget
  (D) build
    WidgetA
      top: Text
      bottom: Text
''');
  }

  test_render_BAD_noDesignTimeConstructor() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Row();
  }
}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.isWidgetClass, isTrue);
    expect(myWidget.renderConstructor, isNull);
    expect(myWidget.stateClassName, isNull);
    expect(myWidget.stateOffset, isNull);
    expect(myWidget.stateLength, isNull);

    expect(computer.instrumentedCode, isNull);
  }

  test_render_BAD_notWidget() async {
    FlutterOutline unitOutline = await _computeOutline('''
class C {}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.isWidgetClass, isNull);
    expect(myWidget.renderConstructor, isNull);
    expect(myWidget.stateClassName, isNull);
    expect(myWidget.stateOffset, isNull);
    expect(myWidget.stateLength, isNull);

    expect(computer.instrumentedCode, isNull);
  }

  test_render_BAD_part() async {
    // Use test.dart as a part of a library.
    // Add the library to the driver so that it is analyzed before the part.
    var libPath = newFile('/test_lib.dart', content: r'''
part 'test.dart';
import 'package:flutter/widgets.dart';
''').path;
    driver.addFile(libPath);

    FlutterOutline unitOutline = await _computeOutline('''
part of 'test_lib.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return new Row();
  }
}
''');

    // Analysis is successful, no errors.
    expect(analysisResult.errors, isEmpty);

    // No instrumentation, because not a library.
    expect(computer.instrumentedCode, isNull);

    // There is forDesignTime() constructor, but we don't handle parts.
    var myWidget = unitOutline.children[0];
    expect(myWidget.isWidgetClass, isNull);
    expect(myWidget.renderConstructor, isNull);
  }

  test_render_instrumentedCode_registerWidgets() async {
    await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new Text('aaa'),
        new Text('bbb'),
      ],
    );
  }
}
''');
    expect(
        computer.instrumentedCode,
        r'''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return _registerWidgetInstance(0, new Row(
      children: <Widget>[
        _registerWidgetInstance(1, new Text('aaa')),
        _registerWidgetInstance(2, new Text('bbb')),
      ],
    ));
  }
}
''' +
            FlutterOutlineComputer.RENDER_APPEND);
  }

  test_render_instrumentedCode_rewriteUri_file() async {
    testPath = resourceProvider.convertPath('/home/user/test/test.dart');
    var libFile = newFile('/home/user/test/my_lib.dart', content: '');

    await _computeOutline('''
import 'package:flutter/widgets.dart';
import 'my_lib.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
    expect(
        computer.instrumentedCode,
        '''
import 'package:flutter/widgets.dart';
import '${libFile.toUri()}';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return _registerWidgetInstance(0, new Container());
  }
}
''' +
            FlutterOutlineComputer.RENDER_APPEND);
  }

  test_render_instrumentedCode_rewriteUri_package() async {
    packageMap['test'] = [newFolder('/home/user/test/lib')];

    testPath = resourceProvider.convertPath('/home/user/test/lib/test.dart');
    newFile('/home/user/test/lib/my_lib.dart', content: '');
    configureDriver();

    await _computeOutline('''
import 'package:flutter/widgets.dart';
import 'my_lib.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
''');
    expect(
        computer.instrumentedCode,
        '''
import 'package:flutter/widgets.dart';
import 'package:test/my_lib.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return _registerWidgetInstance(0, new Container());
  }
}
''' +
            FlutterOutlineComputer.RENDER_APPEND);
  }

  test_render_stateful_createState_blockBody() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatefulWidget {
  MyWidget.forDesignTime();

  @override
  MyWidgetState createState() {
    return new MyWidgetState();
  }
}

class MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return new Container(),
  }
}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.renderConstructor, 'forDesignTime');
    expect(myWidget.stateClassName, 'MyWidgetState');
    expect(myWidget.stateOffset, 192);
    expect(myWidget.stateLength, 130);
  }

  test_render_stateful_createState_expressionBody() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatefulWidget {
  MyWidget.forDesignTime();

  @override
  MyWidgetState createState() => new MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    return new Container(),
  }
}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.isWidgetClass, isTrue);
    expect(myWidget.renderConstructor, 'forDesignTime');
    expect(myWidget.stateClassName, 'MyWidgetState');
    expect(myWidget.stateOffset, 178);
    expect(myWidget.stateLength, 130);
  }

  test_render_stateless() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  MyWidget.forDesignTime();

  @override
  Widget build(BuildContext context) {
    return new Row(
      children: <Widget>[
        new Text('aaa'),
        new Text('bbb'),
      ],
    );
  }
}
''');
    var myWidget = unitOutline.children[0];
    expect(myWidget.isWidgetClass, isTrue);
    expect(myWidget.renderConstructor, 'forDesignTime');
    expect(myWidget.stateClassName, isNull);
    expect(myWidget.stateOffset, isNull);
    expect(myWidget.stateLength, isNull);

    var build = myWidget.children[1];

    var row = build.children[0];
    expect(row.className, 'Row');
    expect(row.id, 0);

    var textA = row.children[0];
    expect(textA.className, 'Text');
    expect(textA.id, 1);

    var textB = row.children[1];
    expect(textB.className, 'Text');
    expect(textB.id, 2);
  }

  test_variableName() async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var text = new Text('aaa');
    return new Center(child: text); // Center
  }
}
''');
    var myWidget = unitOutline.children[0];
    var build = myWidget.children[0];
    expect(build.children, hasLength(2));

    var textNew = build.children[0];
    expect(textNew.kind, FlutterOutlineKind.NEW_INSTANCE);
    expect(textNew.className, 'Text');

    var center = build.children[1];
    expect(center.kind, FlutterOutlineKind.NEW_INSTANCE);
    expect(center.className, 'Center');
    expect(center.children, hasLength(1));

    var textRef = center.children[0];
    expect(textRef.kind, FlutterOutlineKind.VARIABLE);
    expect(textRef.className, 'Text');
    expect(textRef.variableName, 'text');
  }

  Future<FlutterOutline> _computeOutline(String code) async {
    testCode = code;
    newFile(testPath, content: code);
    analysisResult = await driver.getResult(testPath);
    computer = new FlutterOutlineComputer(
        testPath, testCode, analysisResult.lineInfo, analysisResult.unit);
    return computer.compute();
  }

  Future<FlutterOutlineAttribute> _getAttribute(
      String name, String value) async {
    FlutterOutline unitOutline = await _computeOutline('''
import 'package:flutter/widgets.dart';

main() {
  new MyWidget($value);
}

class MyWidget extends StatelessWidget {
  MyWidget($name);

  @override
  Widget build(BuildContext context) {
    return const Text('')
  }
}
''');
    var main = unitOutline.children[0];
    var newMyWidget = main.children[0];

    expect(newMyWidget.attributes, hasLength(1));

    var attribute = newMyWidget.attributes[0];
    expect(attribute.name, name);
    return attribute;
  }

  static String _toText(FlutterOutline outline) {
    var buffer = new StringBuffer();

    void writeOutline(FlutterOutline outline, String indent) {
      buffer.write(indent);

      if (outline.kind == FlutterOutlineKind.DART_ELEMENT) {
        buffer.write('(D) ');
        buffer.writeln(outline.dartElement.name);
      } else {
        if (outline.kind == FlutterOutlineKind.NEW_INSTANCE) {
          if (outline.parentAssociationLabel != null) {
            buffer.write(outline.parentAssociationLabel);
            buffer.write(': ');
          }
          buffer.writeln(outline.className);
        } else {
          fail('Unknown kind: ${outline.kind}');
        }
      }

      if (outline.children != null) {
        for (var child in outline.children) {
          writeOutline(child, '$indent  ');
        }
      }
    }

    for (var child in outline.children) {
      writeOutline(child, '');
    }
    return buffer.toString();
  }
}
