// 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 'package:flutter/foundation.dart';
import 'package:flutter/material.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
  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);
  }
}

typedef NodeDelegator = DiagnosticsSerializationDelegate Function(DiagnosticsNode node, TestDiagnosticsSerializationDelegate delegate);
typedef NodeTruncator = List<DiagnosticsNode> Function(List<DiagnosticsNode> nodes, DiagnosticsNode? owner);
typedef NodeFilter = List<DiagnosticsNode> Function(List<DiagnosticsNode> nodes, DiagnosticsNode owner);

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 NodeFilter? childFilter;
  final NodeFilter? propertyFilter;
  final NodeTruncator? nodeTruncator;
  final NodeDelegator? 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?.call(nodes, owner) ?? nodes;
  }

  @override
  List<DiagnosticsNode> filterProperties(List<DiagnosticsNode> nodes, DiagnosticsNode owner) {
    return propertyFilter?.call(nodes, owner) ?? nodes;
  }

  @override
  final bool includeProperties;

  @override
  final int subtreeDepth;

  @override
  List<DiagnosticsNode> truncateNodesList(List<DiagnosticsNode> nodes, DiagnosticsNode? owner) {
    return nodeTruncator?.call(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,
    );
  }
}
