// Copyright (c) 2024, 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 'dart:io';

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

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

/// The assumed default file mode on Linux and macOS
const _defaultMode = 420; // 644₈

/// Mask for executable bits in file modes.
const _executableMask = 0x49; // 001 001 001

void main() {
  test(
      'archives and uploads empty directories in package. '
      'Maintains the executable bit', () async {
    await d.validPackage().create();
    await d.dir(appPath, [
      d.dir('tool', [d.file('tool.sh', 'commands...')]),
      d.dir('lib', [d.dir('empty')]),
    ]).create();

    if (!Platform.isWindows) {
      Process.runSync(
        'chmod',
        ['+x', p.join(d.sandbox, appPath, 'tool', 'tool.sh')],
      );
    }

    await servePackages();
    await runPub(
      args: ['publish', '--to-archive=archive.tar.gz'],
      output: contains('''
├── CHANGELOG.md (<1 KB)
├── LICENSE (<1 KB)
├── README.md (<1 KB)
├── lib
│   ├── empty
│   └── test_pkg.dart (<1 KB)
├── pubspec.yaml (<1 KB)
└── tool
    └── tool.sh (<1 KB)
'''),
    );
    expect(
      File(p.join(d.sandbox, appPath, 'archive.tar.gz')).existsSync(),
      isTrue,
    );
    final tarReader = TarReader(
      gzip.decoder.bind(
        File(p.join(d.sandbox, appPath, 'archive.tar.gz')).openRead(),
      ),
    );
    final dirs = <String>[];
    while (await tarReader.moveNext()) {
      final entry = tarReader.current;
      if (entry.type == TypeFlag.dir) {
        if (!Platform.isWindows) {
          expect(entry.header.mode, _defaultMode | _executableMask);
        }
        dirs.add(entry.name);
      } else {
        if (!Platform.isWindows) {
          if (entry.name.endsWith('tool.sh')) {
            expect(
              entry.header.mode
                  // chmod +x doesn't sets the executable bit for other users on
                  // some platforms only.
                  |
                  1,
              _defaultMode | _executableMask,
            );
          } else {
            expect(entry.header.mode, _defaultMode);
          }
        }
      }
    }
    dirs.sort();
    expect(dirs, ['lib', 'lib/empty', 'tool']);
    await d.credentialsFile(globalServer, 'access-token').create();
    final pub = await startPublish(globalServer);

    await confirmPublish(pub);
    handleUploadForm(globalServer);
    handleUpload(globalServer);

    globalServer.expect('GET', '/create', (request) {
      return shelf.Response.ok(
        jsonEncode({
          'success': {'message': 'Package test_pkg 1.0.0 uploaded!'},
        }),
      );
    });

    expect(pub.stdout, emits(startsWith('Uploading...')));
    expect(
      pub.stdout,
      emits('Message from server: Package test_pkg 1.0.0 uploaded!'),
    );
    await pub.shouldExit(exit_codes.SUCCESS);
  });

  test('Can download and unpack package with empty directory', () async {
    final server = await servePackages();
    server.serve(
      'foo',
      '1.0.0',
      contents: [
        d.dir('lib', [d.dir('empty', [])]),
      ],
    );
    await d.appDir(dependencies: {'foo': '1.0.0'}).create();
    await pubGet();
    await d.hostedCache([
      d.dir('foo-1.0.0', [
        d.dir('lib', [d.dir('empty')]),
      ]),
    ]).validate();
  });
}
