// Copyright 2013 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.6

import 'dart:io';

import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';

// Ignore members defined on Object.
const Set<String> _kObjectMembers = <String>{
  '==',
  'toString',
  'hashCode',
};

CompilationUnit _parseAndCheckDart(String path) {
  final FeatureSet analyzerFeatures = FeatureSet.fromEnableFlags(<String>['non-nullable']);
  if (!analyzerFeatures.isEnabled(Feature.non_nullable)) {
    throw Exception('non-nullable feature is disabled.');
  }
  final ParseStringResult result = parseFile(path: path, featureSet: analyzerFeatures, throwIfDiagnostics: false);
  if (result.errors.isNotEmpty) {
    result.errors.forEach(stderr.writeln);
    stderr.writeln('Failure!');
    exit(1);
  }
  return result.unit;
}

void main() {
  // These files just contain imports to the part files;
  final CompilationUnit uiUnit = _parseAndCheckDart('lib/ui/ui.dart');
  final CompilationUnit webUnit = _parseAndCheckDart('lib/web_ui/lib/ui.dart');
  final Map<String, ClassDeclaration> uiClasses = <String, ClassDeclaration>{};
  final Map<String, ClassDeclaration> webClasses = <String, ClassDeclaration>{};

  // Gather all public classes from each library. For now we are skiping
  // other top level members.
  _collectPublicClasses(uiUnit, uiClasses, 'lib/ui/');
  _collectPublicClasses(webUnit, webClasses, 'lib/web_ui/lib/');

  if (uiClasses.isEmpty || webClasses.isEmpty) {
    print('Warning: did not resolve any classes.');
  }

  bool failed = false;
  print('Checking ${uiClasses.length} public classes.');
  for (String className in uiClasses.keys) {
    final ClassDeclaration uiClass = uiClasses[className];
    final ClassDeclaration webClass = webClasses[className];
    // If the web class is missing there isn't much left to do here. Print a
    // warning and move along.
    if (webClass == null) {
      failed = true;
      print('Warning: lib/ui/ui.dart contained public class $className, but '
          'this was missing from lib/web_ui/ui.dart.');
      continue;
    }
    // Next will check that the public methods exposed in each library are
    // identical.
    final Map<String, MethodDeclaration> uiMethods =
        <String, MethodDeclaration>{};
    final Map<String, MethodDeclaration> webMethods =
        <String, MethodDeclaration>{};
    final Map<String, ConstructorDeclaration> uiConstructors =
        <String, ConstructorDeclaration>{};
    final Map<String, ConstructorDeclaration> webConstructors =
        <String, ConstructorDeclaration>{};
    _collectPublicMethods(uiClass, uiMethods);
    _collectPublicMethods(webClass, webMethods);
    _collectPublicConstructors(uiClass, uiConstructors);
    _collectPublicConstructors(webClass, webConstructors);

    for (String name in uiConstructors.keys) {
      final ConstructorDeclaration uiConstructor = uiConstructors[name];
      final ConstructorDeclaration webConstructor = webConstructors[name];
      if (webConstructor == null) {
        failed = true;
        print(
          'Warning: lib/ui/ui.dart $className.$name is missing from lib/web_ui/ui.dart.',
        );
        continue;
      }

      if (uiConstructor.parameters.parameters.length !=
          webConstructor.parameters.parameters.length) {
        failed = true;
        print(
            'Warning: lib/ui/ui.dart $className.$name has a different parameter '
            'length than in lib/web_ui/ui.dart.');
      }

      for (int i = 0;
          i < uiConstructor.parameters.parameters.length &&
              i < uiConstructor.parameters.parameters.length;
          i++) {
        // Technically you could re-order named parameters and still be valid,
        // but we enforce that they are identical.
        for (int i = 0;
            i < uiConstructor.parameters.parameters.length &&
                i < webConstructor.parameters.parameters.length;
            i++) {
          final FormalParameter uiParam =
              uiConstructor.parameters.parameters[i];
          final FormalParameter webParam =
              webConstructor.parameters.parameters[i];
          if (webParam.identifier.name != uiParam.identifier.name) {
            failed = true;
            print('Warning: lib/ui/ui.dart $className.$name parameter $i'
                ' ${uiParam.identifier.name} has a different name in lib/web_ui/ui.dart.');
          }
          if (uiParam.isPositional != webParam.isPositional) {
            failed = true;
            print('Warning: lib/ui/ui.dart $className.$name parameter $i'
                '${uiParam.identifier.name} is positional, but not in lib/web_ui/ui.dart.');
          }
          if (uiParam.isNamed != webParam.isNamed) {
            failed = true;
            print('Warning: lib/ui/ui.dart $className.$name parameter $i'
                '${uiParam.identifier.name} is named, but not in lib/web_ui/ui.dart.');
          }
        }
      }
    }

    for (String methodName in uiMethods.keys) {
      if (_kObjectMembers.contains(methodName)) {
        continue;
      }
      final MethodDeclaration uiMethod = uiMethods[methodName];
      final MethodDeclaration webMethod = webMethods[methodName];
      if (webMethod == null) {
        failed = true;
        print(
          'Warning: lib/ui/ui.dart $className.$methodName is missing from lib/web_ui/ui.dart.',
        );
        continue;
      }
      if (uiMethod.parameters == null || webMethod.parameters == null) {
        continue;
      }
      if (uiMethod.parameters.parameters.length !=
          webMethod.parameters.parameters.length) {
        failed = true;
        print(
            'Warning: lib/ui/ui.dart $className.$methodName has a different parameter '
            'length than in lib/web_ui/ui.dart.');
      }
      // Technically you could re-order named parameters and still be valid,
      // but we enforce that they are identical.
      for (int i = 0;
          i < uiMethod.parameters.parameters.length &&
              i < webMethod.parameters.parameters.length;
          i++) {
        final FormalParameter uiParam = uiMethod.parameters.parameters[i];
        final FormalParameter webParam = webMethod.parameters.parameters[i];
        if (webParam.identifier.name != uiParam.identifier.name) {
          failed = true;
          print('Warning: lib/ui/ui.dart $className.$methodName parameter $i'
              ' ${uiParam.identifier.name} has a different name in lib/web_ui/ui.dart.');
        }
        if (uiParam.isPositional != webParam.isPositional) {
          failed = true;
          print('Warning: lib/ui/ui.dart $className.$methodName parameter $i'
              '${uiParam.identifier.name} is positional, but not in lib/web_ui/ui.dart.');
        }
        if (uiParam.isNamed != webParam.isNamed) {
          failed = true;
          print('Warning: lib/ui/ui.dart $className.$methodName parameter $i'
              '${uiParam.identifier.name} is named, but not in lib/web_ui/ui.dart.');
        }
      }
      // check return type.
      if (uiMethod.returnType?.toString() != webMethod.returnType?.toString()) {
        // allow dynamic in web implementation.
        if (webMethod.returnType?.toString() != 'dynamic') {
          failed = true;
          print(
            'Warning: $className.$methodName return type mismatch:\n'
            '  lib/ui/ui.dart     : ${uiMethod.returnType?.toSource()}\n'
            '  lib/web_ui/ui.dart : ${webMethod.returnType?.toSource()}');
        }
      }
    }
  }
  if (failed) {
    print('Failure!');
    exit(1);
  }
  print('Success!');
  exit(0);
}

// Collects all public classes defined by the part files of [unit].
void _collectPublicClasses(CompilationUnit unit,
    Map<String, ClassDeclaration> destination, String root) {
  for (Directive directive in unit.directives) {
    if (directive is! PartDirective) {
      continue;
    }
    final PartDirective partDirective = directive as PartDirective;
    final String literalUri = partDirective.uri.toString();
    final CompilationUnit subUnit = _parseAndCheckDart('$root${literalUri.substring(1, literalUri.length - 1)}');
    for (CompilationUnitMember member in subUnit.declarations) {
      if (member is! ClassDeclaration) {
        continue;
      }
      final ClassDeclaration classDeclaration = member as ClassDeclaration;
      if (classDeclaration.name.name.startsWith('_')) {
        continue;
      }
      destination[classDeclaration.name.name] = classDeclaration;
    }
  }
}

void _collectPublicConstructors(ClassDeclaration classDeclaration,
    Map<String, ConstructorDeclaration> destination) {
  for (ClassMember member in classDeclaration.members) {
    if (member is! ConstructorDeclaration) {
      continue;
    }
    final ConstructorDeclaration method = member as ConstructorDeclaration;
    if (method?.name?.name == null) {
      destination['Unnamed Constructor'] = method;
      continue;
    }
    if (method.name.name.startsWith('_')) {
      continue;
    }
    destination[method.name.name] = method;
  }
}

void _collectPublicMethods(ClassDeclaration classDeclaration,
    Map<String, MethodDeclaration> destination) {
  for (ClassMember member in classDeclaration.members) {
    if (member is! MethodDeclaration) {
      continue;
    }
    final MethodDeclaration method = member as MethodDeclaration;
    if (method.name.name.startsWith('_')) {
      continue;
    }
    destination[method.name.name] = method;
  }
}
