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

import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/flutter/widget_descriptions.dart';
import 'package:test/test.dart';

import '../../../abstract_single_unit.dart';

class WidgetDescriptionBase extends AbstractSingleUnitTest {
  final descriptions = WidgetDescriptions();

  void assertExpectedChange(SetPropertyValueResult result, String expected) {
    expect(result.errorCode, isNull);

    var change = result.change!;

    expect(change.edits, hasLength(1));
    var fileEdit = change.edits[0];
    expect(fileEdit.file, testAnalysisResult.path);

    var actual = SourceEdit.applySequence(
      testAnalysisResult.content!,
      fileEdit.edits,
    );
    expect(actual, expected);
  }

  void assertPropertyJsonText(
    protocol.FlutterWidgetProperty property,
    String expected,
  ) {
    var json = property.toJson();
    _removeNotInterestingElements(json);

    var actual = JsonEncoder.withIndent('  ').convert(json);

    expected = expected.trimRight();
    if (actual != expected) {
      print('-----');
      print(actual);
      print('-----');
    }
    expect(actual, expected);
  }

  Future<protocol.FlutterGetWidgetDescriptionResult?> getDescription(
      String search) async {
    var content = testAnalysisResult.content!;

    var offset = content.indexOf(search);
    if (offset == -1) {
      fail('Not found: $search');
    }

    if (content.contains(search, offset + search.length)) {
      fail('More than one: $search');
    }

    return descriptions.getDescription(testAnalysisResult, offset);
  }

  protocol.FlutterWidgetProperty getNestedProperty(
      protocol.FlutterWidgetProperty parentProperty, String name) {
    var nestedProperties = parentProperty.children!;
    return nestedProperties.singleWhere(
      (property) => property.name == name,
    );
  }

  Future<protocol.FlutterWidgetProperty> getWidgetProperty(
      String widgetSearch, String name) async {
    var widgetDescription = (await getDescription(widgetSearch))!;

    var properties = widgetDescription.properties;
    return properties.singleWhere(
      (property) => property.name == name,
    );
  }

  @override
  void setUp() {
    super.setUp();
    writeTestPackageConfig(
      flutter: true,
    );
  }

  void _removeNotInterestingElements(Map<String, dynamic> json) {
    json.remove('documentation');

    var id = json.remove('id') as int;
    expect(id, isNotNull);

    var editor = json['editor'];
    if (editor is Map<String, dynamic>) {
      if (editor['kind'] == 'ENUM' || editor['kind'] == 'ENUM_LIKE') {
        var items = editor['enumItems'];
        if (items is List<Map<String, dynamic>>) {
          for (var item in items) {
            item.remove('documentation');
          }
        }
      }
    }

    var value = json['value'];
    if (value is Map<String, dynamic>) {
      var enumItem = value['enumValue'];
      if (enumItem is Map<String, dynamic>) {
        enumItem.remove('documentation');
      }
    }

    var children = json['children'];
    if (children is List<Map<String, dynamic>>) {
      children.forEach(_removeNotInterestingElements);
    }
  }
}
