// Copyright 2020 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 'dart:core';
import 'dart:io';
import 'package:path/path.dart' as path;
import 'dart:io' as io_internals show exit;

final bool hasColor = stdout.supportsAnsiEscapes;
final String bold = hasColor ? '\x1B[1m' : ''; // used for shard titles
final String red = hasColor ? '\x1B[31m' : ''; // used for errors
final String reset = hasColor ? '\x1B[0m' : '';
final String reverse = hasColor ? '\x1B[7m' : ''; // used for clocks

Future<void> main(List<String> arguments) async {
  print('$clock STARTING ANALYSIS');
  try {
    await run(arguments);
  } on ExitException catch (error) {
    error.apply();
  }
  print('$clock ${bold}Analysis successful.$reset');
}

Future<void> run(List<String> arguments) async {
  final String cocoonPath = path.join(path.dirname(Platform.script.path), '..');
  print('$clock Root path: $cocoonPath');
  print('$clock Licenses...');
  await verifyNoMissingLicense(cocoonPath);
}

// TESTS
String _generateLicense(String prefix) {
  return '${prefix}Copyright (2014|2015|2016|2017|2018|2019|2020|2021|2022) The Flutter Authors. All rights reserved.\n'
      '${prefix}Use of this source code is governed by a BSD-style license that can be\n'
      '${prefix}found in the LICENSE file.';
}

Future<void> verifyNoMissingLicense(String workingDirectory, {bool checkMinimums = true}) async {
  final int? overrideMinimumMatches = checkMinimums ? null : 0;
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'dart',
    overrideMinimumMatches ?? 2000,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'java',
    overrideMinimumMatches ?? 39,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'h',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'm',
    overrideMinimumMatches ?? 30,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'swift',
    overrideMinimumMatches ?? 10,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gradle',
    overrideMinimumMatches ?? 100,
    _generateLicense('// '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'gn',
    overrideMinimumMatches ?? 0,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'Dockerfile',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'sh',
    overrideMinimumMatches ?? 1,
    '#!/bin/bash\n' + _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'bat',
    overrideMinimumMatches ?? 1,
    _generateLicense(':: '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'ps1',
    overrideMinimumMatches ?? 1,
    _generateLicense('# '),
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'html',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
    trailingBlank: false,
  );
  await _verifyNoMissingLicenseForExtension(
    workingDirectory,
    'xml',
    overrideMinimumMatches ?? 1,
    '<!-- ${_generateLicense('')} -->',
  );
}

Future<void> _verifyNoMissingLicenseForExtension(
  String workingDirectory,
  String extension,
  int minimumMatches,
  String license, {
  bool trailingBlank = true,
}) async {
  assert(!license.endsWith('\n'));
  final String licensePattern = license + '\n' + (trailingBlank ? '\n' : '');
  final List<String> errors = <String>[];
  for (final File file in _allFiles(workingDirectory, extension, minimumMatches: minimumMatches)) {
    final String contents = file.readAsStringSync().replaceAll('\r\n', '\n');
    if (contents.isEmpty) continue; // let's not go down the /bin/true rabbit hole
    if (!contents.startsWith(RegExp(licensePattern))) errors.add(file.path);
  }
  // Fail if any errors
  if (errors.isNotEmpty) {
    final String s = errors.length == 1 ? ' does' : 's do';
    exitWithError(<String>[
      '${bold}The following ${errors.length} file$s not have the right license header:$reset',
      ...errors,
      'The expected license header is:',
      license,
      if (trailingBlank) '...followed by a blank line.',
    ]);
  }
}

Iterable<File> _allFiles(String workingDirectory, String extension, {required int minimumMatches}) sync* {
  assert(!extension.startsWith('.'), 'Extension argument should not start with a period.');
  final Set<FileSystemEntity> pending = <FileSystemEntity>{Directory(workingDirectory)};
  int matches = 0;
  while (pending.isNotEmpty) {
    final FileSystemEntity entity = pending.first;
    pending.remove(entity);
    if (path.extension(entity.path) == '.tmpl') continue;
    if (entity is File) {
      if (_isGeneratedPluginRegistrant(entity)) continue;
      if (path.basename(entity.path) == 'AppDelegate.h') continue;
      if (path.basename(entity.path) == 'flutter_export_environment.sh') continue;
      if (path.basename(entity.path) == 'gradlew.bat') continue;
      if (path.basename(entity.path) == 'Runner-Bridging-Header.h') continue;
      if (path.basename(entity.path).endsWith('g.dart')) continue;
      if (path.basename(entity.path).endsWith('mocks.mocks.dart')) continue;
      if (path.basename(entity.path).endsWith('pb.dart')) continue;
      if (path.basename(entity.path).endsWith('pbenum.dart')) continue;
      if (path.basename(entity.path).endsWith('pbjson.dart')) continue;
      if (path.basename(entity.path).endsWith('pbserver.dart')) continue;
      if (path.extension(entity.path) == '.$extension') {
        matches += 1;
        yield entity;
      }
      if (path.basename(entity.path) == 'Dockerfile' && extension == 'Dockerfile') {
        matches += 1;
        yield entity;
      }
    } else if (entity is Directory) {
      if (File(path.join(entity.path, '.dartignore')).existsSync()) continue;
      if (path.basename(entity.path) == '.git') continue;
      if (path.basename(entity.path) == '.gradle') continue;
      if (path.basename(entity.path) == '.dart_tool') continue;
      if (_isPartOfAppTemplate(entity)) continue;
      pending.addAll(entity.listSync());
    }
  }
  assert(
    matches >= minimumMatches,
    'Expected to find at least $minimumMatches files with extension ".$extension" in "$workingDirectory", but only found $matches.',
  );
}

bool _isPartOfAppTemplate(Directory directory) {
  const Set<String> templateDirs = <String>{
    'android',
    'build',
    'ios',
    'linux',
    'macos',
    'web',
    'windows',
  };
  // Project directories will have a metadata file in them.
  if (File(path.join(directory.parent.path, '.metadata')).existsSync()) {
    return templateDirs.contains(path.basename(directory.path));
  }
  return false;
}

bool _isGeneratedPluginRegistrant(File file) {
  final String filename = path.basenameWithoutExtension(file.path);
  return !path.split(file.path).contains('.pub-cache') &&
      (filename == 'generated_plugin_registrant' || filename == 'GeneratedPluginRegistrant');
}

void exitWithError(List<String> messages) {
  final String redLine = '$red━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$reset';
  print(redLine);
  messages.forEach(print);
  print(redLine);
  exit(1);
}

class ExitException implements Exception {
  ExitException(this.exitCode);

  final int exitCode;

  void apply() {
    io_internals.exit(exitCode);
  }
}

String get clock {
  final DateTime now = DateTime.now();
  return '$reverse▌'
      '${now.hour.toString().padLeft(2, "0")}:'
      '${now.minute.toString().padLeft(2, "0")}:'
      '${now.second.toString().padLeft(2, "0")}'
      '▐$reset';
}
