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

import 'dart:async';

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:file/record_replay.dart';
import 'package:file/testing.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'common_tests.dart';

void main() {
  group('Replay', () {
    RecordingFileSystem recordingFileSystem;
    MemoryFileSystem memoryFileSystem;
    LiveRecording recording;

    setUp(() {
      memoryFileSystem = new MemoryFileSystem();
      recordingFileSystem = new RecordingFileSystem(
        delegate: memoryFileSystem,
        destination: new MemoryFileSystem().directory('/tmp')..createSync(),
      );
      recording = recordingFileSystem.recording;
    });

    /// Creates a new [ReplayFileSystem] that will replay a recording of the
    /// events that have been recorded within [recordingFileSystem] thus far.
    Future<ReplayFileSystem> replay() async {
      await recording.flush();
      return new ReplayFileSystem(recording: recording.destination);
    }

    runCommonTests(
      () => recordingFileSystem,
      replay: replay,
      skip: <String>[
        // ReplayFileSystem does not yet support futures & streams that throw
        'File > openRead > throws.*',
        'File > openWrite > throws.*',
        'File > openWrite > ioSink > throwsIfAddError',
        'File > openWrite > ioSink > addStream > blocks.*',

        'File > open', // Not yet implemented in MemoryFileSystem
      ],
    );

    group('ReplayFileSystem', () {
      test('directory', () async {
        recordingFileSystem.directory('/foo');
        ReplayFileSystem fs = await replay();
        Directory dir = fs.directory('/foo');
        expect(dir, isDirectory);
        expect(() => dir.path, throwsNoMatchingInvocationError);
        expect(() => fs.directory('/foo'), throwsNoMatchingInvocationError);
      });

      test('file', () async {
        recordingFileSystem.file('/foo');
        ReplayFileSystem fs = await replay();
        expect(fs.file('/foo'), isFile);
        expect(() => fs.file('/foo'), throwsNoMatchingInvocationError);
      });

      test('link', () async {
        recordingFileSystem.link('/foo');
        ReplayFileSystem fs = await replay();
        expect(fs.link('/foo'), isLink);
        expect(() => fs.link('/foo'), throwsNoMatchingInvocationError);
      });

      test('path', () async {
        path.Context context = recordingFileSystem.path;
        ReplayFileSystem fs = await replay();
        path.Context replayContext = fs.path;
        expect(() => fs.path, throwsNoMatchingInvocationError);
        expect(replayContext.style, context.style);
        expect(replayContext.current, context.current);
      });

      test('systemTempDirectory', () async {
        recordingFileSystem.systemTempDirectory;
        ReplayFileSystem fs = await replay();
        Directory dir = fs.systemTempDirectory;
        expect(dir, isDirectory);
        expect(() => dir.path, throwsNoMatchingInvocationError);
        expect(() => fs.systemTempDirectory, throwsNoMatchingInvocationError);
      });

      group('currentDirectory', () {
        test('get', () async {
          recordingFileSystem.currentDirectory;
          ReplayFileSystem fs = await replay();
          Directory dir = fs.currentDirectory;
          expect(dir, isDirectory);
          expect(() => dir.path, throwsNoMatchingInvocationError);
          expect(() => fs.currentDirectory, throwsNoMatchingInvocationError);
        });

        test('setToString', () async {
          memoryFileSystem.directory('/foo').createSync();
          recordingFileSystem.currentDirectory = '/foo';
          ReplayFileSystem fs = await replay();
          expect(() => fs.currentDirectory = '/bar',
              throwsNoMatchingInvocationError);
          fs.currentDirectory = '/foo';
          expect(() => fs.currentDirectory = '/foo',
              throwsNoMatchingInvocationError);
        });

        test('setToDirectory', () async {
          Directory dir = await recordingFileSystem.directory('/foo').create();
          recordingFileSystem.currentDirectory = dir;
          ReplayFileSystem fs = await replay();
          Directory replayDir = fs.directory('/foo');
          expect(() => fs.directory('/foo'), throwsNoMatchingInvocationError);
          fs.currentDirectory = replayDir;
          expect(() => fs.currentDirectory = replayDir,
              throwsNoMatchingInvocationError);
        });
      });

      test('stat', () async {
        FileStat stat = await recordingFileSystem.stat('/');
        ReplayFileSystem fs = await replay();
        Future<FileStat> replayStatFuture = fs.stat('/');
        expect(() => fs.stat('/'), throwsNoMatchingInvocationError);
        expect(replayStatFuture, isFuture);
        FileStat replayStat = await replayStatFuture;
        expect(replayStat.accessed, stat.accessed);
        expect(replayStat.changed, stat.changed);
        expect(replayStat.modified, stat.modified);
        expect(replayStat.mode, stat.mode);
        expect(replayStat.type, stat.type);
        expect(replayStat.size, stat.size);
        expect(replayStat.modeString(), stat.modeString());
      });

      test('statSync', () async {
        FileStat stat = recordingFileSystem.statSync('/');
        ReplayFileSystem fs = await replay();
        FileStat replayStat = fs.statSync('/');
        expect(() => fs.statSync('/'), throwsNoMatchingInvocationError);
        expect(replayStat.accessed, stat.accessed);
        expect(replayStat.changed, stat.changed);
        expect(replayStat.modified, stat.modified);
        expect(replayStat.mode, stat.mode);
        expect(replayStat.type, stat.type);
        expect(replayStat.size, stat.size);
        expect(replayStat.modeString(), stat.modeString());
      });

      test('identical', () async {
        memoryFileSystem.directory('/foo').createSync();
        bool identical = await recordingFileSystem.identical('/', '/foo');
        ReplayFileSystem fs = await replay();
        Future<bool> replayIdenticalFuture = fs.identical('/', '/foo');
        expect(
            () => fs.identical('/', '/foo'), throwsNoMatchingInvocationError);
        expect(replayIdenticalFuture, isFuture);
        expect(await replayIdenticalFuture, identical);
      });

      test('identicalSync', () async {
        memoryFileSystem.directory('/foo').createSync();
        bool identical = recordingFileSystem.identicalSync('/', '/foo');
        ReplayFileSystem fs = await replay();
        bool replayIdentical = fs.identicalSync('/', '/foo');
        expect(() => fs.identicalSync('/', '/foo'),
            throwsNoMatchingInvocationError);
        expect(replayIdentical, identical);
      });

      test('isWatchSupported', () async {
        bool isWatchSupported = recordingFileSystem.isWatchSupported;
        ReplayFileSystem fs = await replay();
        expect(fs.isWatchSupported, isWatchSupported);
        expect(() => fs.isWatchSupported, throwsNoMatchingInvocationError);
      });

      test('type', () async {
        FileSystemEntityType type = await recordingFileSystem.type('/');
        ReplayFileSystem fs = await replay();
        Future<FileSystemEntityType> replayTypeFuture = fs.type('/');
        expect(() => fs.type('/'), throwsNoMatchingInvocationError);
        expect(replayTypeFuture, isFuture);
        expect(await replayTypeFuture, type);
      });

      test('typeSync', () async {
        FileSystemEntityType type = recordingFileSystem.typeSync('/');
        ReplayFileSystem fs = await replay();
        FileSystemEntityType replayType = fs.typeSync('/');
        expect(() => fs.typeSync('/'), throwsNoMatchingInvocationError);
        expect(replayType, type);
      });
    });
  });
}

/// Successfully matches against an instance of [Future].
const Matcher isFuture = const isInstanceOf<Future<dynamic>>();
