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

// @dart = 2.8

import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/ide_config.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/template.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/test_flutter_command_runner.dart';

void main() {
  group('ide_config', () {
    Directory tempDir;
    Directory templateDir;
    Directory intellijDir;
    Directory toolsDir;

    Map<String, String> _getFilesystemContents([ Directory root ]) {
      final String tempPath = tempDir.absolute.path;
      final List<String> paths =
        (root ?? tempDir).listSync(recursive: true).map((FileSystemEntity entity) {
          final String relativePath = globals.fs.path.relative(entity.path, from: tempPath);
          return relativePath;
        }).toList();
      final Map<String, String> contents = <String, String>{};
      for (final String path in paths) {
        final String absPath = globals.fs.path.join(tempPath, path);
        if (globals.fs.isDirectorySync(absPath)) {
          contents[path] = 'dir';
        } else if (globals.fs.isFileSync(absPath)) {
          contents[path] = globals.fs.file(absPath).readAsStringSync();
        }
      }
      return contents;
    }

    Map<String, String> _getManifest(Directory base, String marker, { bool isTemplate = false }) {
      final String basePath = globals.fs.path.relative(base.path, from: tempDir.absolute.path);
      final String suffix = isTemplate ? Template.copyTemplateExtension : '';
      return <String, String>{
        globals.fs.path.join(basePath, '.idea'): 'dir',
        globals.fs.path.join(basePath, '.idea', 'modules.xml$suffix'): 'modules $marker',
        globals.fs.path.join(basePath, '.idea', 'vcs.xml$suffix'): 'vcs $marker',
        globals.fs.path.join(basePath, '.idea', '.name$suffix'): 'codeStyleSettings $marker',
        globals.fs.path.join(basePath, '.idea', 'runConfigurations'): 'dir',
        globals.fs.path.join(basePath, '.idea', 'runConfigurations', 'hello_world.xml$suffix'): 'hello_world $marker',
        globals.fs.path.join(basePath, 'flutter.iml$suffix'): 'flutter $marker',
        globals.fs.path.join(basePath, 'packages', 'new', 'deep.iml$suffix'): 'deep $marker',
        globals.fs.path.join(basePath, 'example', 'gallery', 'android.iml$suffix'): 'android $marker',
      };
    }

    void _populateDir(Map<String, String> manifest) {
      for (final String key in manifest.keys) {
        if (manifest[key] == 'dir') {
          tempDir.childDirectory(key).createSync(recursive: true);
        }
      }
      for (final String key in manifest.keys) {
        if (manifest[key] != 'dir') {
          tempDir.childFile(key)
            ..createSync(recursive: true)
            ..writeAsStringSync(manifest[key]);
        }
      }
    }

    bool _fileOrDirectoryExists(String path) {
      final String absPath = globals.fs.path.join(tempDir.absolute.path, path);
      return globals.fs.file(absPath).existsSync() || globals.fs.directory(absPath).existsSync();
    }

    Future<void> _updateIdeConfig({
      Directory dir,
      List<String> args = const <String>[],
      Map<String, String> expectedContents = const <String, String>{},
      List<String> unexpectedPaths = const <String>[],
    }) async {
      dir ??= tempDir;
      Cache.flutterRoot = tempDir.absolute.path;
      final IdeConfigCommand command = IdeConfigCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>[
        'ide-config',
        ...args,
      ]);

      for (final String path in expectedContents.keys) {
        final String absPath = globals.fs.path.join(tempDir.absolute.path, path);
        expect(_fileOrDirectoryExists(globals.fs.path.join(dir.path, path)), true,
            reason: "$path doesn't exist");
        if (globals.fs.file(absPath).existsSync()) {
          expect(globals.fs.file(absPath).readAsStringSync(), equals(expectedContents[path]),
              reason: "$path contents don't match");
        }
      }
      for (final String path in unexpectedPaths) {
        expect(_fileOrDirectoryExists(globals.fs.path.join(dir.path, path)), false, reason: '$path exists');
      }
    }

    setUpAll(() {
      Cache.disableLocking();
    });

    setUp(() {
      tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_ide_config_test.');
      final Directory packagesDir = tempDir.childDirectory('packages')..createSync(recursive: true);
      toolsDir = packagesDir.childDirectory('flutter_tools')..createSync();
      templateDir = toolsDir.childDirectory('ide_templates')..createSync();
      intellijDir = templateDir.childDirectory('intellij')..createSync();
    });

    tearDown(() {
      tryToDelete(tempDir);
    });

    testUsingContext("doesn't touch existing files without --overwrite", () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      _populateDir(templateManifest);
      _populateDir(flutterManifest);
      final Map<String, String> expectedContents = _getFilesystemContents();
      return _updateIdeConfig(
        expectedContents: expectedContents,
      );
    });

    testUsingContext('creates non-existent files', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'template',
      );
      _populateDir(templateManifest);
      final Map<String, String> expectedContents = <String, String>{
        ...templateManifest,
        ...flutterManifest,
      };
      return _updateIdeConfig(
        expectedContents: expectedContents,
      );
    });

    testUsingContext('overwrites existing files with --overwrite', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      _populateDir(templateManifest);
      _populateDir(flutterManifest);
      final Map<String, String> overwrittenManifest = _getManifest(
        tempDir,
        'template',
      );
      final Map<String, String> expectedContents = <String, String>{
        ...templateManifest,
        ...overwrittenManifest,
      };
      return _updateIdeConfig(
        args: <String>['--overwrite'],
        expectedContents: expectedContents,
      );
    });

    testUsingContext('only adds new templates without --overwrite', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      final String flutterIml = globals.fs.path.join(
        'packages',
        'flutter_tools',
        'ide_templates',
        'intellij',
        'flutter.iml${Template.copyTemplateExtension}',
      );
      templateManifest.remove(flutterIml);
      _populateDir(templateManifest);
      templateManifest[flutterIml] = 'flutter existing';
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      _populateDir(flutterManifest);
      final Map<String, String> expectedContents = <String, String>{
        ...flutterManifest,
        ...templateManifest,
      };
      return _updateIdeConfig(
        args: <String>['--update-templates'],
        expectedContents: expectedContents,
      );
    });

    testUsingContext('update all templates with --overwrite', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      _populateDir(templateManifest);
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      _populateDir(flutterManifest);
      final Map<String, String> updatedTemplates = _getManifest(
        intellijDir,
        'existing',
        isTemplate: true,
      );
      final Map<String, String> expectedContents = <String, String>{
        ...flutterManifest,
        ...updatedTemplates,
      };
      return _updateIdeConfig(
        args: <String>['--update-templates', '--overwrite'],
        expectedContents: expectedContents,
      );
    });

    testUsingContext('removes deleted imls with --overwrite', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      _populateDir(templateManifest);
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      flutterManifest.remove('flutter.iml');
      _populateDir(flutterManifest);
      final Map<String, String> updatedTemplates = _getManifest(
        intellijDir,
        'existing',
        isTemplate: true,
      );
      final String flutterIml = globals.fs.path.join(
        'packages',
        'flutter_tools',
        'ide_templates',
        'intellij',
        'flutter.iml${Template.copyTemplateExtension}',
      );
      updatedTemplates.remove(flutterIml);
      final Map<String, String> expectedContents = <String, String>{
        ...flutterManifest,
        ...updatedTemplates,
      };
      return _updateIdeConfig(
        args: <String>['--update-templates', '--overwrite'],
        expectedContents: expectedContents,
      );
    });

    testUsingContext('removes deleted imls with --overwrite, including empty parent dirs', () async {
      final Map<String, String> templateManifest = _getManifest(
        intellijDir,
        'template',
        isTemplate: true,
      );
      _populateDir(templateManifest);
      final Map<String, String> flutterManifest = _getManifest(
        tempDir,
        'existing',
      );
      flutterManifest.remove(globals.fs.path.join('packages', 'new', 'deep.iml'));
      _populateDir(flutterManifest);
      final Map<String, String> updatedTemplates = _getManifest(
        intellijDir,
        'existing',
        isTemplate: true,
      );
      String deepIml = globals.fs.path.join(
        'packages',
        'flutter_tools',
        'ide_templates',
        'intellij');
      // Remove the all the dir entries too.
      updatedTemplates.remove(deepIml);
      deepIml = globals.fs.path.join(deepIml, 'packages');
      updatedTemplates.remove(deepIml);
      deepIml = globals.fs.path.join(deepIml, 'new');
      updatedTemplates.remove(deepIml);
      deepIml = globals.fs.path.join(deepIml, 'deep.iml');
      updatedTemplates.remove(deepIml);
      final Map<String, String> expectedContents = <String, String>{
        ...flutterManifest,
        ...updatedTemplates,
      };
      return _updateIdeConfig(
        args: <String>['--update-templates', '--overwrite'],
        expectedContents: expectedContents,
      );
    });

  });
}
