// 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.

// @dart = 2.8

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('Element diagnostics json includes widgetRuntimeType', () async {
    final Element element = _TestElement();

    final Map<String, Object> json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
    expect(json['widgetRuntimeType'], 'Placeholder');
    expect(json['stateful'], isFalse);
  });

  test('StatefulElement diagnostics are stateful', () {
    final Element element = StatefulElement(const Tooltip(message: 'foo'));

    final Map<String, Object> json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
    expect(json['widgetRuntimeType'], 'Tooltip');
    expect(json['stateful'], isTrue);
  });

  group('Serialization', () {
    final TestTree testTree = TestTree(
      properties: <DiagnosticsNode>[
        StringProperty('stringProperty1', 'value1', quoted: false),
        DoubleProperty('doubleProperty1', 42.5),
        DoubleProperty('roundedProperty', 1.0 / 3.0),
        StringProperty('DO_NOT_SHOW', 'DO_NOT_SHOW', level: DiagnosticLevel.hidden, quoted: false),
        DiagnosticsProperty<Object>('DO_NOT_SHOW_NULL', null, defaultValue: null),
        DiagnosticsProperty<Object>('nullProperty', null),
        StringProperty('node_type', '<root node>', showName: false, quoted: false),
      ],
      children: <TestTree>[
        TestTree(name: 'node A'),
        TestTree(
          name: 'node B',
          properties: <DiagnosticsNode>[
            StringProperty('p1', 'v1', quoted: false),
            StringProperty('p2', 'v2', quoted: false),
          ],
          children: <TestTree>[
            TestTree(name: 'node B1'),
            TestTree(
              name: 'node B2',
              properties: <DiagnosticsNode>[StringProperty('property1', 'value1', quoted: false)],
            ),
            TestTree(
              name: 'node B3',
              properties: <DiagnosticsNode>[
                StringProperty('node_type', '<leaf node>', showName: false, quoted: false),
                IntProperty('foo', 42),
              ],
            ),
          ],
        ),
        TestTree(
          name: 'node C',
          properties: <DiagnosticsNode>[
            StringProperty('foo', 'multi\nline\nvalue!', quoted: false),
          ],
        ),
      ],
    );

    test('default', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate());
      expect(result.containsKey('properties'), isFalse);
      expect(result.containsKey('children'), isFalse);
    });

    test('subtreeDepth 1', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1));
      expect(result.containsKey('properties'), isFalse);
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children[0].containsKey('children'), isFalse);
      expect(children[1].containsKey('children'), isFalse);
      expect(children[2].containsKey('children'), isFalse);
    });

    test('subtreeDepth 5', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5));
      expect(result.containsKey('properties'), isFalse);
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children[0]['children'], hasLength(0));
      expect(children[1]['children'], hasLength(3));
      expect(children[2]['children'], hasLength(0));
    });

    test('includeProperties', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(includeProperties: true));
      expect(result.containsKey('children'), isFalse);
      expect(result['properties'], hasLength(7));
    });

    test('includeProperties with subtreedepth 1', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(
        includeProperties: true,
        subtreeDepth: 1,
      ));
      expect(result['properties'], hasLength(7));
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(3));
      expect(children[0]['properties'], hasLength(0));
      expect(children[1]['properties'], hasLength(2));
      expect(children[2]['properties'], hasLength(1));
    });

    test('additionalNodeProperties', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(const TestDiagnosticsSerializationDelegate(
        includeProperties: true,
        subtreeDepth: 1,
        additionalNodePropertiesMap: <String, Object>{
          'foo': true,
        },
      ));
      expect(result['foo'], isTrue);
      final List<Map<String, Object>> properties = result['properties'] as List<Map<String, Object>>;
      expect(properties, hasLength(7));
      expect(properties.every((Map<String, Object> property) => property['foo'] == true), isTrue);

      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(3));
      expect(children.every((Map<String, Object> child) => child['foo'] == true), isTrue);
    });

    test('filterProperties - sublist', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          includeProperties: true,
          propertyFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
            return nodes.whereType<StringProperty>().toList();
          },
      ));
      final List<Map<String, Object>> properties = result['properties'] as List<Map<String, Object>>;
      expect(properties, hasLength(3));
      expect(properties.every((Map<String, Object> property) => property['type'] == 'StringProperty'), isTrue);
    });

    test('filterProperties - replace', () {
      bool replaced = false;
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          includeProperties: true,
          propertyFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
            if (replaced) {
              return nodes;
            }
            replaced = true;
            return <DiagnosticsNode>[
              StringProperty('foo', 'bar'),
            ];
          },
      ));
      final List<Map<String, Object>> properties = result['properties'] as List<Map<String, Object>>;
      expect(properties, hasLength(1));
      expect(properties.single['name'], 'foo');
    });

    test('filterChildren - sublist', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          subtreeDepth: 1,
          childFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
            return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList();
          },
      ));
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(1));
    });

    test('filterChildren - replace', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          subtreeDepth: 1,
          childFilter: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
            return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList();
          },
      ));
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(3));
      expect(children.first['name'], 'child node B1');
    });

    test('nodeTruncator', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          subtreeDepth: 5,
          includeProperties: true,
          nodeTruncator: (List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
            return nodes.take(2).toList();
          },
      ));
      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(3));
      expect(children.last['truncated'], isTrue);

      final List<Map<String, Object>> properties = result['properties'] as List<Map<String, Object>>;
      expect(properties, hasLength(3));
      expect(properties.last['truncated'], isTrue);
    });

    test('delegateForAddingNodes', () {
      final Map<String, Object> result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate(
          subtreeDepth: 5,
          includeProperties: true,
          nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) {
            return delegate.copyWith(includeProperties: false);
          },
      ));
      final List<Map<String, Object>> properties = result['properties'] as List<Map<String, Object>>;
      expect(properties, hasLength(7));
      expect(properties.every((Map<String, Object> property) => !property.containsKey('properties')), isTrue);

      final List<Map<String, Object>> children = result['children'] as List<Map<String, Object>>;
      expect(children, hasLength(3));
      expect(children.every((Map<String, Object> child) => !child.containsKey('properties')), isTrue);
    });
  });
}

class _TestElement extends Element {
  _TestElement() : super(const Placeholder());

  @override
  void performRebuild() {
    // Intentionally left empty.
  }

  @override
  bool get debugDoingBuild => throw UnimplementedError();
}

class TestTree extends Object with DiagnosticableTreeMixin {
  TestTree({
    this.name,
    this.style,
    this.children = const <TestTree>[],
    this.properties = const <DiagnosticsNode>[],
  });

  final String name;
  final List<TestTree> children;
  final List<DiagnosticsNode> properties;
  final DiagnosticsTreeStyle style;

  @override
  List<DiagnosticsNode> debugDescribeChildren() => <DiagnosticsNode>[
    for (final TestTree child in children)
      child.toDiagnosticsNode(
        name: 'child ${child.name}',
        style: child.style,
      ),
  ];

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    if (style != null)
      properties.defaultDiagnosticsTreeStyle = style;

    this.properties.forEach(properties.add);
  }
}

class TestDiagnosticsSerializationDelegate implements DiagnosticsSerializationDelegate {
  const TestDiagnosticsSerializationDelegate({
    this.includeProperties = false,
    this.subtreeDepth = 0,
    this.additionalNodePropertiesMap = const <String, Object>{},
    this.childFilter,
    this.propertyFilter,
    this.nodeTruncator,
    this.nodeDelegator,
  });

  final Map<String, Object> additionalNodePropertiesMap;
  final List<DiagnosticsNode> Function(List<DiagnosticsNode> nodes, DiagnosticsNode owner) childFilter;
  final List<DiagnosticsNode> Function(List<DiagnosticsNode> nodes, DiagnosticsNode owner) propertyFilter;
  final List<DiagnosticsNode> Function(List<DiagnosticsNode> nodes, DiagnosticsNode owner) nodeTruncator;
  final DiagnosticsSerializationDelegate Function(DiagnosticsNode node, TestDiagnosticsSerializationDelegate delegate) nodeDelegator;

  @override
  Map<String, Object> additionalNodeProperties(DiagnosticsNode node) {
    return additionalNodePropertiesMap;
  }

  @override
  DiagnosticsSerializationDelegate delegateForNode(DiagnosticsNode node) {
    if (nodeDelegator != null) {
      return nodeDelegator(node, this);
    }
    return subtreeDepth > 0 ? copyWith(subtreeDepth: subtreeDepth - 1) : this;
  }

  @override
  bool get expandPropertyValues => false;

  @override
  List<DiagnosticsNode> filterChildren(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
    return childFilter != null ? childFilter(nodes, owner) : nodes;
  }

  @override
  List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
    return propertyFilter != null ? propertyFilter(nodes, owner) : nodes;
  }

  @override
  final bool includeProperties;

  @override
  final int subtreeDepth;

  @override
  List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
    return nodeTruncator != null ? nodeTruncator(nodes, owner) : nodes;
  }

  @override
  DiagnosticsSerializationDelegate copyWith({int subtreeDepth, bool includeProperties}) {
    return TestDiagnosticsSerializationDelegate(
      includeProperties: includeProperties ?? this.includeProperties,
      subtreeDepth: subtreeDepth ?? this.subtreeDepth,
      additionalNodePropertiesMap: additionalNodePropertiesMap,
      childFilter: childFilter,
      propertyFilter: propertyFilter,
      nodeTruncator: nodeTruncator,
      nodeDelegator: nodeDelegator,
    );
  }
}
