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

import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:pub/src/io.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';

import '../../descriptor.dart' as d;
import '../../test_pub.dart';

void main() {
  test('checks out a package from Git', () async {
    ensureGit();

    await d.git(
      'foo.git',
      [d.libDir('foo'), d.libPubspec('foo', '1.0.0')],
    ).create();

    await d.appDir(
      dependencies: {
        'foo': {'git': '../foo.git'},
      },
    ).create();

    await pubGet();

    final lockfile = loadYaml(
      File(p.join(d.sandbox, appPath, 'pubspec.lock')).readAsStringSync(),
    );
    expect(
      lockfile['packages']['foo']['description']['url'],
      '../foo.git',
      reason:
          'The relative path should be preserved, and be a url (forward slashes on all platforms)',
    );

    await d.dir(cachePath, [
      d.dir('git', [
        d.dir('cache', [d.gitPackageRepoCacheDir('foo')]),
        d.gitPackageRevisionCacheDir('foo'),
      ]),
    ]).validate();

    expect(packageSpec('foo'), isNotNull);
  });

  test('checks out a package from Git using non-json YAML', () async {
    ensureGit();

    await d.git('foo.git', [
      d.libDir('foo'),
      d.file('pubspec.yaml', '''
name: foo
environment:
  sdk: '$defaultSdkConstraint'
'''),
    ]).create();

    await d.appDir(
      dependencies: {
        'foo': {'git': '../foo.git'},
      },
    ).create();

    await pubGet();
  });

  test(
      'checks out a package from Git with a name that is not a valid '
      'file name in the url', () async {
    ensureGit();

    final descriptor =
        d.git('foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]);

    await descriptor.create();
    await runProcess(
      'git',
      ['update-server-info'],
      workingDir: descriptor.io.path,
    );
    const funkyName = '@:+*foo';

    final server =
        await _serveDirectory(p.join(descriptor.io.path, '.git'), funkyName);

    await d.appDir(
      dependencies: {
        'foo': {'git': 'http://localhost:${server.url.port}/$funkyName'},
      },
    ).create();

    await pubGet();

    await d.dir(cachePath, [
      d.dir('git', [
        d.dir('cache', [d.gitPackageRepoCacheDir('____foo')]),
        d.gitPackageRevisionCacheDir('foo', repoName: '____foo'),
      ]),
    ]).validate();

    expect(packageSpec('foo'), isNotNull);
  });
}

Future<shelf.Server> _serveDirectory(String dir, String prefix) async {
  final server = await shelf_io.IOServer.bind('localhost', 0);
  server.mount((request) async {
    final path = request.url.path.substring(prefix.length + 1);
    try {
      return shelf.Response.ok(await File(p.join(dir, path)).readAsBytes());
    } catch (_) {
      return shelf.Response.notFound('File "$path" not found.');
    }
  });
  return server;
}
