// 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:convert';

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

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

void main() {
  test('Warns about discontinued dependencies', () async {
    final server = await servePackages();
    server.serve('foo', '1.2.3', deps: {'transitive': 'any'});
    server.serve('transitive', '1.0.0');
    await d.appDir(dependencies: {'foo': '1.2.3'}).create();
    await pubGet();

    server
      ..discontinue('foo')
      ..discontinue('transitive');
    // A pub get straight away will not trigger the warning, as we cache
    // responses for a while.
    await pubGet();
    final fooVersionsCache =
        p.join(globalServer.cachingPath, '.cache', 'foo-versions.json');
    final transitiveVersionsCache =
        p.join(globalServer.cachingPath, '.cache', 'transitive-versions.json');
    expect(fileExists(fooVersionsCache), isTrue);
    expect(fileExists(transitiveVersionsCache), isTrue);
    deleteEntry(fooVersionsCache);
    deleteEntry(transitiveVersionsCache);
    // We warn only about the direct dependency here:
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued)
Got dependencies!
1 package is discontinued.
''',
    );
    expect(fileExists(fooVersionsCache), isTrue);
    final c = json.decode(readTextFile(fooVersionsCache)) as Map;
    // Make the cache artificially old.
    c['_fetchedAt'] =
        DateTime.now().subtract(const Duration(days: 5)).toIso8601String();
    writeTextFile(fooVersionsCache, json.encode(c));

    server.discontinue('foo', replacementText: 'bar');

    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    final c2 = json.decode(readTextFile(fooVersionsCache)) as Map;
    // Make a bad cached value to test that responses are actually from cache.
    c2['isDiscontinued'] = false;
    writeTextFile(fooVersionsCache, json.encode(c2));
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
Got dependencies!''',
    );
    // Repairing the cache should reset the package listing caches.
    await runPub(args: ['cache', 'repair']);
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    // Test that --offline won't try to access the server for retrieving the
    // status.
    server.serveErrors();
    await pubGet(
      args: ['--offline'],
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    deleteEntry(fooVersionsCache);
    deleteEntry(transitiveVersionsCache);
    await pubGet(
      args: ['--offline'],
      output: '''
Resolving dependencies...
Downloading packages...
Got dependencies!
''',
    );
  });

  test('Warns about discontinued dev dependencies', () async {
    final builder = await servePackages();
    builder
      ..serve('foo', '1.2.3', deps: {'transitive': 'any'})
      ..serve('transitive', '1.0.0');

    await d.dir(appPath, [
      d.file('pubspec.yaml', '''
name: myapp
dependencies:

dev_dependencies:
  foo: 1.2.3
environment:
  sdk: '$defaultSdkConstraint'
'''),
    ]).create();
    await pubGet();

    builder
      ..discontinue('foo')
      ..discontinue('transitive');
    // A pub get straight away will not trigger the warning, as we cache
    // responses for a while.
    await pubGet();
    final fooVersionsCache =
        p.join(globalServer.cachingPath, '.cache', 'foo-versions.json');
    expect(fileExists(fooVersionsCache), isTrue);
    deleteEntry(fooVersionsCache);
    // We warn only about the direct dependency here:
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued)
Got dependencies!
1 package is discontinued.
''',
    );
    expect(fileExists(fooVersionsCache), isTrue);
    final c = json.decode(readTextFile(fooVersionsCache)) as Map;
    // Make the cache artificially old.
    c['_fetchedAt'] =
        DateTime.now().subtract(const Duration(days: 5)).toIso8601String();
    writeTextFile(fooVersionsCache, json.encode(c));
    builder.discontinue('foo', replacementText: 'bar');
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    final c2 = json.decode(readTextFile(fooVersionsCache)) as Map;
    // Make a bad cached value to test that responses are actually from cache.
    c2['isDiscontinued'] = false;
    writeTextFile(fooVersionsCache, json.encode(c2));
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
Got dependencies!''',
    );
    // Repairing the cache should reset the package listing caches.
    await runPub(args: ['cache', 'repair']);
    await pubGet(
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    // Test that --offline won't try to access the server for retrieving the
    // status.
    builder.serveErrors();
    await pubGet(
      args: ['--offline'],
      output: '''
Resolving dependencies...
Downloading packages...
  foo 1.2.3 (discontinued replaced by bar)
Got dependencies!
1 package is discontinued.''',
    );
    deleteEntry(fooVersionsCache);
    await pubGet(
      args: ['--offline'],
      output: '''
Resolving dependencies...
Downloading packages...
Got dependencies!
''',
    );
  });

  test('get does not fail when status listing fails', () async {
    final server = await servePackages();
    server.serve('foo', '1.2.3');
    await d.appDir(dependencies: {'foo': '1.2.3'}).create();
    await pubGet();
    final fooVersionsCache =
        p.join(globalServer.cachingPath, '.cache', 'foo-versions.json');
    expect(fileExists(fooVersionsCache), isTrue);
    deleteEntry(fooVersionsCache);
    // Serve 400 on all requests.
    globalServer.handle(
      RegExp('.*'),
      (shelf.Request request) => shelf.Response.notFound('Not found'),
    );

    /// Even if we fail to get status we still report success if versions don't
    /// unlock.
    await pubGet();
  });
}
