// Copyright (c) 2017, 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.

@TestOn('vm')
library;

import 'dart:io' as io;

import 'package:file/chroot.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:test/test.dart';

import 'common_tests.dart';

void main() {
  group('ChrootFileSystem', () {
    ChrootFileSystem createMemoryBackedChrootFileSystem() {
      var fs = MemoryFileSystem();
      fs.directory('/tmp').createSync();
      return ChrootFileSystem(fs, '/tmp');
    }

    // TODO(jamesderlin): Make ChrootFile.openSync return a delegating
    // RandomAccessFile that uses the chroot'd path.
    var skipCommon = <String>[
      // ignore: lines_longer_than_80_chars
      'File > open > .* > RandomAccessFile > read > openReadHandleDoesNotChange',
      'File > open > .* > RandomAccessFile > openWriteHandleDoesNotChange',
    ];

    group('memoryBacked', () {
      runCommonTests(createMemoryBackedChrootFileSystem, skip: skipCommon);
    });

    group('localBacked', () {
      late ChrootFileSystem fs;
      late io.Directory tmp;

      setUp(() {
        tmp = io.Directory.systemTemp.createTempSync('file_test_');
        tmp = io.Directory(tmp.resolveSymbolicLinksSync());
        fs = ChrootFileSystem(const LocalFileSystem(), tmp.path);
      });

      tearDown(() {
        tmp.deleteSync(recursive: true);
      });

      runCommonTests(
        () => fs,
        skip: <String>[
          // https://github.com/dart-lang/sdk/issues/28275
          'Link > rename > throwsIfDestinationExistsAsDirectory',

          // https://github.com/dart-lang/sdk/issues/28277
          'Link > rename > throwsIfDestinationExistsAsFile',

          ...skipCommon,
        ],
      );
    }, skip: io.Platform.isWindows);

    group('chrootSpecific', () {
      late ChrootFileSystem fs;
      late MemoryFileSystem mem;

      setUp(() {
        fs = createMemoryBackedChrootFileSystem();
        mem = fs.delegate as MemoryFileSystem;
      });

      group('FileSystem', () {
        group('currentDirectory', () {
          test('staysInJailIfSetToParentOfRoot', () {
            fs.currentDirectory = '../../../..';
            fs.file('foo').createSync();
            expect(mem.file('/tmp/foo'), exists);
          });

          test('throwsIfSetToSymlinkToDirectoryOutsideJail', () {
            mem.directory('/bar').createSync();
            mem.link('/tmp/foo').createSync('/bar');
            expectFileSystemException(ErrorCodes.ENOENT, () {
              fs.currentDirectory = '/foo';
            });
          });
        });

        group('stat', () {
          test('isNotFoundForJailbreakPath', () {
            mem.file('/foo').createSync();
            expect(fs.statSync('../foo').type, FileSystemEntityType.notFound);
          });

          test('isNotFoundForSymlinkWithJailbreakTarget', () {
            mem.file('/foo').createSync();
            mem.link('/tmp/bar').createSync('/foo');
            expect(mem.statSync('/tmp/bar').type, FileSystemEntityType.file);
            expect(fs.statSync('/bar').type, FileSystemEntityType.notFound);
          });

          test('isNotFoundForSymlinkToOutsideAndBackInsideJail', () {
            mem.file('/tmp/bar').createSync();
            mem.link('/foo').createSync('/tmp/bar');
            mem.link('/tmp/baz').createSync('/foo');
            expect(mem.statSync('/tmp/baz').type, FileSystemEntityType.file);
            expect(fs.statSync('/baz').type, FileSystemEntityType.notFound);
          });
        });

        group('type', () {
          test('isNotFoundForJailbreakPath', () {
            mem.file('/foo').createSync();
            expect(fs.typeSync('../foo'), FileSystemEntityType.notFound);
          });

          test('isNotFoundForSymlinkWithJailbreakTarget', () {
            mem.file('/foo').createSync();
            mem.link('/tmp/bar').createSync('/foo');
            expect(mem.typeSync('/tmp/bar'), FileSystemEntityType.file);
            expect(fs.typeSync('/bar'), FileSystemEntityType.notFound);
          });

          test('isNotFoundForSymlinkToOutsideAndBackInsideJail', () {
            mem.file('/tmp/bar').createSync();
            mem.link('/foo').createSync('/tmp/bar');
            mem.link('/tmp/baz').createSync('/foo');
            expect(mem.typeSync('/tmp/baz'), FileSystemEntityType.file);
            expect(fs.typeSync('/baz'), FileSystemEntityType.notFound);
          });
        });
      });

      group('File', () {
        group('delegate', () {
          test('referencesRootEntityForJailbreakPath', () {
            mem.file('/foo').createSync();
            dynamic f = fs.file('../foo');
            // ignore: avoid_dynamic_calls
            expect(f.delegate.path, '/tmp/foo');
          });
        });

        group('create', () {
          test('createsAtRootIfPathReferencesJailbreakFile', () {
            fs.file('../foo').createSync();
            expect(mem.file('/foo'), isNot(exists));
            expect(mem.file('/tmp/foo'), exists);
          });
        });

        group('copy', () {
          test('copiesToRootDirectoryIfDestinationIsJailbreakPath', () {
            var f = fs.file('/foo')..createSync();
            f.copySync('../bar');
            expect(mem.file('/bar'), isNot(exists));
            expect(mem.file('/tmp/bar'), exists);
          });
        });
      });

      group('Link', () {
        group('target', () {
          test('chrootAndDelegateFileSystemsReturnSameValue', () {
            mem.file('/foo').createSync();
            mem.link('/tmp/bar').createSync('/foo');
            mem.link('/tmp/baz').createSync('../foo');
            expect(mem.link('/tmp/bar').targetSync(), '/foo');
            expect(fs.link('/bar').targetSync(), '/foo');
            expect(mem.link('/tmp/baz').targetSync(), '../foo');
            expect(fs.link('/baz').targetSync(), '../foo');
          });
        });
      });
    });
  });
}
