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

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_system/depfile.dart';
import 'package:platform/platform.dart';

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

void main() {
  FileSystem fileSystem;
  DepfileService depfileService;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    depfileService = DepfileService(
      logger: BufferLogger.test(),
      fileSystem: fileSystem,
      platform: FakePlatform(operatingSystem: 'linux'),
    );
  });
  testWithoutContext('Can parse depfile from file', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
a.txt: b.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs.single.path, 'b.txt');
    expect(depfile.outputs.single.path, 'a.txt');
  });

  testWithoutContext('Can parse depfile with multiple inputs', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
a.txt: b.txt c.txt d.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs.map((File file) => file.path), <String>[
      'b.txt',
      'c.txt',
      'd.txt',
    ]);
    expect(depfile.outputs.single.path, 'a.txt');
  });

  testWithoutContext('Can parse depfile with multiple outputs', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync('''
a.txt c.txt d.txt: b.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs.single.path, 'b.txt');
    expect(depfile.outputs.map((File file) => file.path), <String>[
      'a.txt',
      'c.txt',
      'd.txt',
    ]);
  });

  testWithoutContext('Can parse depfile with windows file paths', () {
    fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
    depfileService = DepfileService(
      logger: BufferLogger.test(),
      fileSystem: fileSystem,
      platform: FakePlatform(operatingSystem: 'windows'),
    );
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
C:\\a.txt: C:\\b.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs.single.path, r'C:\b.txt');
    expect(depfile.outputs.single.path, r'C:\a.txt');
  });

  testWithoutContext('Can escape depfile with windows file paths and spaces in directory names', () {
    fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
    depfileService = DepfileService(
      logger: BufferLogger.test(),
      fileSystem: fileSystem,
      platform: FakePlatform(operatingSystem: 'windows'),
    );
    final File inputFile = fileSystem.directory(r'Hello Flutter').childFile('a.txt').absolute
      ..createSync(recursive: true);
    final File outputFile = fileSystem.directory(r'Hello Flutter').childFile('b.txt').absolute
      ..createSync();
    final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
    final File outputDepfile = fileSystem.file('depfile');
    depfileService.writeToFile(depfile, outputDepfile);

    expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\a.txt'));
    expect(outputDepfile.readAsStringSync(), contains(r'C:\\Hello\ Flutter\\b.txt'));
  });

  testWithoutContext('Can escape depfile with spaces in directory names', () {
    final File inputFile = fileSystem.directory(r'Hello Flutter').childFile('a.txt').absolute
      ..createSync(recursive: true);
    final File outputFile = fileSystem.directory(r'Hello Flutter').childFile('b.txt').absolute
      ..createSync();
    final Depfile depfile = Depfile(<File>[inputFile], <File>[outputFile]);
    final File outputDepfile = fileSystem.file('depfile');
    depfileService.writeToFile(depfile, outputDepfile);

    expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/a.txt'));
    expect(outputDepfile.readAsStringSync(), contains(r'/Hello\ Flutter/b.txt'));
  });


  testWithoutContext('Resillient to weird whitespace', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
a.txt
  : b.txt    c.txt


''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs, hasLength(2));
    expect(depfile.outputs.single.path, 'a.txt');
  });

  testWithoutContext('Resillient to duplicate files', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
a.txt: b.txt b.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs.single.path, 'b.txt');
    expect(depfile.outputs.single.path, 'a.txt');
  });

  testWithoutContext('Resillient to malformed file, missing :', () {
    final File depfileSource = fileSystem.file('example.d')..writeAsStringSync(r'''
a.text b.txt
''');
    final Depfile depfile = depfileService.parse(depfileSource);

    expect(depfile.inputs, isEmpty);
    expect(depfile.outputs, isEmpty);
  });

  testWithoutContext('Can parse dart2js output format', () {
    final File dart2jsDependencyFile = fileSystem.file('main.dart.js.deps')..writeAsStringSync(r'''
file:///Users/foo/collection.dart
file:///Users/foo/algorithms.dart
file:///Users/foo/canonicalized_map.dart
''');

    final Depfile depfile = depfileService.parseDart2js(dart2jsDependencyFile, fileSystem.file('foo.dart.js'));

    expect(depfile.inputs.map((File file) => file.path), <String>[
      fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'collection.dart')),
      fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'algorithms.dart')),
      fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'canonicalized_map.dart')),
    ]);
    expect(depfile.outputs.single.path, 'foo.dart.js');
  });

  testWithoutContext('Can parse handle invalid uri', () {
    final File dart2jsDependencyFile = fileSystem.file('main.dart.js.deps')..writeAsStringSync('''
file:///Users/foo/collection.dart
abcdevf
file:///Users/foo/canonicalized_map.dart
''');

    final Depfile depfile = depfileService.parseDart2js(dart2jsDependencyFile, fileSystem.file('foo.dart.js'));

    expect(depfile.inputs.map((File file) => file.path), <String>[
      fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'collection.dart')),
      fileSystem.path.absolute(fileSystem.path.join('Users', 'foo', 'canonicalized_map.dart')),
    ]);
    expect(depfile.outputs.single.path, 'foo.dart.js');
  });
}
