// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library packages_files_test;

import 'package:path/path.dart' as path;
import 'package:scheduled_test/scheduled_test.dart';

import '../lib/src/entrypoint.dart';
import '../lib/src/io.dart';
import '../lib/src/system_cache.dart';
import 'descriptor.dart' as d;
import 'test_pub.dart';

var root;
var entrypoint;

main() {
  initConfig();

  group('not in a git repo', () {
    setUp(() {
      d.appDir().create();
      scheduleEntrypoint();
    });


    integration('lists files recursively', () {
      d.dir(appPath, [
        d.file('file1.txt', 'contents'),
        d.file('file2.txt', 'contents'),
        d.dir('subdir', [
          d.file('subfile1.txt', 'subcontents'),
          d.file('subfile2.txt', 'subcontents')
        ])
      ]).create();

      schedule(() {
        expect(entrypoint.packageFiles(), completion(unorderedEquals([
          path.join(root, 'pubspec.yaml'),
          path.join(root, 'file1.txt'),
          path.join(root, 'file2.txt'),
          path.join(root, 'subdir', 'subfile1.txt'),
          path.join(root, 'subdir', 'subfile2.txt')
        ])));
      });
    });

    commonTests();
  });

  group('with git', () {
    setUp(() {
      ensureGit();
      d.git(appPath, [d.appPubspec()]).create();
      scheduleEntrypoint();
    });

    integration("includes files that are or aren't checked in", () {
      d.dir(appPath, [
        d.file('file1.txt', 'contents'),
        d.file('file2.txt', 'contents'),
        d.dir('subdir', [
          d.file('subfile1.txt', 'subcontents'),
          d.file('subfile2.txt', 'subcontents')
        ])
      ]).create();

      schedule(() {
        expect(entrypoint.packageFiles(), completion(unorderedEquals([
          path.join(root, 'pubspec.yaml'),
          path.join(root, 'file1.txt'),
          path.join(root, 'file2.txt'),
          path.join(root, 'subdir', 'subfile1.txt'),
          path.join(root, 'subdir', 'subfile2.txt')
        ])));
      });
    });

    integration("ignores files that are gitignored", () {
      d.dir(appPath, [
        d.file('.gitignore', '*.txt'),
        d.file('file1.txt', 'contents'),
        d.file('file2.text', 'contents'),
        d.dir('subdir', [
          d.file('subfile1.txt', 'subcontents'),
          d.file('subfile2.text', 'subcontents')
        ])
      ]).create();

      schedule(() {
        expect(entrypoint.packageFiles(), completion(unorderedEquals([
          path.join(root, 'pubspec.yaml'),
          path.join(root, '.gitignore'),
          path.join(root, 'file2.text'),
          path.join(root, 'subdir', 'subfile2.text')
        ])));
      });
    });

    commonTests();
  });
}

void scheduleEntrypoint() {
  schedule(() {
    root = path.join(sandboxDir, appPath);
    entrypoint = new Entrypoint(root, new SystemCache.withSources(root));
  }, 'initializing entrypoint');

  currentSchedule.onComplete.schedule(() {
    entrypoint = null;
  }, 'nulling entrypoint');
}

void commonTests() {
  integration('ignores broken symlinks', () {
    // Windows requires us to symlink to a directory that actually exists.
    d.dir(appPath, [d.dir('target')]).create();
    scheduleSymlink(path.join(appPath, 'target'), path.join(appPath, 'link'));
    schedule(() => deleteEntry(path.join(sandboxDir, appPath, 'target')));

    schedule(() {
      expect(entrypoint.packageFiles(),
          completion(equals([path.join(root, 'pubspec.yaml')])));
    });
  });

  integration('ignores pubspec.lock files', () {
    d.dir(appPath, [
      d.file('pubspec.lock'),
      d.dir('subdir', [d.file('pubspec.lock')])
    ]).create();

    schedule(() {
      expect(entrypoint.packageFiles(),
          completion(equals([path.join(root, 'pubspec.yaml')])));
    });
  });

  integration('ignores packages directories', () {
    d.dir(appPath, [
      d.dir('packages', [d.file('file.txt', 'contents')]),
      d.dir('subdir', [
        d.dir('packages', [d.file('subfile.txt', 'subcontents')]),
      ])
    ]).create();

    schedule(() {
      expect(entrypoint.packageFiles(),
          completion(equals([path.join(root, 'pubspec.yaml')])));
    });
  });

  integration('allows pubspec.lock directories', () {
    d.dir(appPath, [
      d.dir('pubspec.lock', [
        d.file('file.txt', 'contents'),
      ])
    ]).create();

    schedule(() {
      expect(entrypoint.packageFiles(), completion(unorderedEquals([
        path.join(root, 'pubspec.yaml'),
        path.join(root, 'pubspec.lock', 'file.txt')
      ])));
    });
  });

  group('and "beneath"', () {
    integration('only lists files beneath the given root', () {
      d.dir(appPath, [
        d.file('file1.txt', 'contents'),
        d.file('file2.txt', 'contents'),
        d.dir('subdir', [
          d.file('subfile1.txt', 'subcontents'),
          d.file('subfile2.txt', 'subcontents'),
          d.dir('subsubdir', [
            d.file('subsubfile1.txt', 'subsubcontents'),
            d.file('subsubfile2.txt', 'subsubcontents'),
          ])
        ])
      ]).create();

      schedule(() {
        expect(entrypoint.packageFiles(beneath: path.join(root, 'subdir')),
            completion(unorderedEquals([
          path.join(root, 'subdir', 'subfile1.txt'),
          path.join(root, 'subdir', 'subfile2.txt'),
          path.join(root, 'subdir', 'subsubdir', 'subsubfile1.txt'),
          path.join(root, 'subdir', 'subsubdir', 'subsubfile2.txt')
        ])));
      });
    });

    integration("doesn't care if the root is blacklisted", () {
      d.dir(appPath, [
        d.file('file1.txt', 'contents'),
        d.file('file2.txt', 'contents'),
        d.dir('packages', [
          d.file('subfile1.txt', 'subcontents'),
          d.file('subfile2.txt', 'subcontents'),
          d.dir('subsubdir', [
            d.file('subsubfile1.txt', 'subsubcontents'),
            d.file('subsubfile2.txt', 'subsubcontents')
          ])
        ])
      ]).create();

      schedule(() {
        expect(entrypoint.packageFiles(beneath: path.join(root, 'packages')),
            completion(unorderedEquals([
          path.join(root, 'packages', 'subfile1.txt'),
          path.join(root, 'packages', 'subfile2.txt'),
          path.join(root, 'packages', 'subsubdir', 'subsubfile1.txt'),
          path.join(root, 'packages', 'subsubdir', 'subsubfile2.txt')
        ])));
      });
    });
  });
}
