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

import 'dart:io' as io;

import 'package:args/command_runner.dart';
import 'package:path/path.dart' as path;

import 'environment.dart';

class LicensesCommand extends Command<bool> {
  @override
  final String name = 'check-licenses';

  @override
  final String description = 'Check license headers.';

  @override
  bool run() {
    _checkLicenseHeaders();
    return true;
  }

  void _checkLicenseHeaders() {
    final List<io.File> allSourceFiles =
        _flatListSourceFiles(environment.webUiRootDir);
    _expect(allSourceFiles.isNotEmpty,
        'Dart source listing of ${environment.webUiRootDir.path} must not be empty.');

    final List<String> allDartPaths =
        allSourceFiles.map((io.File f) => f.path).toList();

    for (final String expectedDirectory in const <String>[
      'lib',
      'test',
      'dev',
    ]) {
      final String expectedAbsoluteDirectory =
          path.join(environment.webUiRootDir.path, expectedDirectory);
      _expect(
        allDartPaths
            .where((String p) => p.startsWith(expectedAbsoluteDirectory))
            .isNotEmpty,
        'Must include the $expectedDirectory/ directory',
      );
    }

    allSourceFiles.forEach(_expectLicenseHeader);
    print('License headers OK!');
  }

  final RegExp _copyRegex =
      RegExp(r'// Copyright 2013 The Flutter Authors\. All rights reserved\.');

  void _expectLicenseHeader(io.File file) {
    final List<String> head = file.readAsStringSync().split('\n').take(3).toList();

    _expect(head.length >= 3, 'File too short: ${file.path}');
    _expect(
      _copyRegex.firstMatch(head[0]) != null,
      'Invalid first line of license header in file ${file.path}',
    );
    _expect(
      head[1] ==
          '// Use of this source code is governed by a BSD-style license that can be',
      'Invalid second line of license header in file ${file.path}',
    );
    _expect(
      head[2] == '// found in the LICENSE file.',
      'Invalid third line of license header in file ${file.path}',
    );
  }

  void _expect(bool value, String requirement) {
    if (!value) {
      throw Exception('Test failed: $requirement');
    }
  }

  List<io.File> _flatListSourceFiles(io.Directory directory) {
    return directory.listSync(recursive: true).whereType<io.File>().where((io.File f) {
      if (!f.path.endsWith('.dart') && !f.path.endsWith('.js')) {
        // Not a source file we're checking.
        return false;
      }
      if (path.isWithin(environment.webUiBuildDir.path, f.path) ||
          path.isWithin(environment.webUiDartToolDir.path, f.path)) {
        // Generated files.
        return false;
      }
      return true;
    }).toList();
  }
}
