// Copyright 2018 The Fuchsia Authors. 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 'dart:convert';
import 'dart:typed_data';

import 'package:fidl/fidl.dart';
import 'package:fidl_fuchsia_io/fidl_async.dart';
import 'package:fuchsia_vfs/vfs.dart';
import 'package:test/test.dart';
import 'package:zircon/zircon.dart';

void main() {
  group('pseudo dir: ', () {
    test('inode number', () {
      Vnode dir = PseudoDir();
      expect(dir.inodeNumber(), inoUnknown);
    });

    test('type', () {
      Vnode dir = PseudoDir();
      expect(dir.type(), direntTypeDirectory);
    });

    test('basic', () {
      PseudoDir dir = PseudoDir();
      var key1 = 'key1';
      var key2 = 'key2';

      var node1 = _TestVnode();
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.lookup(key1), node1);

      var node2 = _TestVnode();
      expect(dir.addNode(key2, node2), ZX.OK);
      expect(dir.lookup(key2), node2);

      // make sure key1 is still there
      expect(dir.lookup(key1), node1);
    });

    test('duplicate key', () {
      PseudoDir dir = PseudoDir();
      var key = 'key';
      var node = _TestVnode();
      var dupNode = _TestVnode();
      expect(dir.addNode(key, node), ZX.OK);
      expect(dir.addNode(key, dupNode), ZX.ERR_ALREADY_EXISTS);

      // check that key was not replaced
      expect(dir.lookup(key), node);
    });

    test('remove node', () {
      PseudoDir dir = PseudoDir();
      var key = 'key';
      var node = _TestVnode();
      expect(dir.addNode(key, node), ZX.OK);
      expect(dir.lookup(key), node);

      expect(dir.removeNode(key), ZX.OK);
      expect(dir.lookup(key), null);

      // add again and check
      expect(dir.addNode(key, node), ZX.OK);
      expect(dir.lookup(key), node);
    });

    test('remove when multiple keys', () {
      PseudoDir dir = PseudoDir();
      var key1 = 'key1';
      var key2 = 'key2';
      var node1 = _TestVnode();
      var node2 = _TestVnode();
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.addNode(key2, node2), ZX.OK);
      expect(dir.lookup(key1), node1);
      expect(dir.lookup(key2), node2);

      expect(dir.removeNode(key1), ZX.OK);
      expect(dir.lookup(key1), null);

      // check that key2 is still there
      expect(dir.lookup(key2), node2);

      // add again and check
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.lookup(key1), node1);
      expect(dir.lookup(key2), node2);
    });

    test('key order is maintained', () {
      PseudoDir dir = PseudoDir();
      var key1 = 'key1';
      var key2 = 'key2';
      var key3 = 'key3';
      var node1 = _TestVnode();
      var node2 = _TestVnode();
      var node3 = _TestVnode();
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.addNode(key2, node2), ZX.OK);
      expect(dir.addNode(key3, node3), ZX.OK);

      expect(dir.listNodeNames(), [key1, key2, key3]);

      // order maintained after removing node
      expect(dir.removeNode(key1), ZX.OK);
      expect(dir.listNodeNames(), [key2, key3]);

      // add again and check
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.listNodeNames(), [key2, key3, key1]);
    });

    test('remove and isEmpty', () {
      PseudoDir dir = PseudoDir();
      var key1 = 'key1';
      var key2 = 'key2';
      var key3 = 'key3';
      var node1 = _TestVnode();
      var node2 = _TestVnode();
      var node3 = _TestVnode();
      expect(dir.isEmpty(), true);
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.addNode(key2, node2), ZX.OK);
      expect(dir.addNode(key3, node3), ZX.OK);
      expect(dir.isEmpty(), false);

      expect(dir.removeNode(key1), ZX.OK);
      expect(dir.isEmpty(), false);
      dir.removeAllNodes();
      expect(dir.isEmpty(), true);
      expect(dir.listNodeNames(), []);
      // make sure that keys are really gone
      expect(dir.lookup(key2), null);
      expect(dir.lookup(key3), null);

      // add again and check
      expect(dir.addNode(key1, node1), ZX.OK);
      expect(dir.isEmpty(), false);
      expect(dir.lookup(key1), node1);
      expect(dir.listNodeNames(), [key1]);
    });
  });

  group('pseudo dir server: ', () {
    group('open fails: ', () {
      test('invalid flags', () async {
        PseudoDir dir = PseudoDir();
        var invalidFlags = [
          openFlagAppend,
          openFlagCreate,
          openFlagCreateIfAbsent,
          openFlagNoRemote,
          openFlagTruncate,
          openRightAdmin,
        ];

        var i = 0;
        for (var flag in invalidFlags) {
          DirectoryProxy proxy = DirectoryProxy();
          var status = dir.connect(flag | openFlagDescribe, 0,
              InterfaceRequest(proxy.ctrl.request().passChannel()));
          expect(status, isNot(ZX.OK), reason: 'flagIndex: $i');
          i++;
          await proxy.onOpen.first.then((response) {
            expect(response.s, status);
            expect(response.info, isNull);
          }).catchError((err) async {
            fail(err.toString());
          });
        }
      });

      test('invalid mode', () async {
        PseudoDir dir = PseudoDir();
        var invalidModes = [
          modeTypeBlockDevice,
          modeTypeFile,
          modeTypeService,
          modeTypeService,
          modeTypeSocket
        ];

        var i = 0;
        for (var mode in invalidModes) {
          DirectoryProxy proxy = DirectoryProxy();
          var status = dir.connect(openFlagDescribe, mode,
              InterfaceRequest(proxy.ctrl.request().passChannel()));
          expect(status, ZX.ERR_INVALID_ARGS, reason: 'modeIndex: $i');
          i++;
          await proxy.onOpen.first.then((response) {
            expect(response.s, status);
            expect(response.info, isNull);
          }).catchError((err) async {
            fail(err.toString());
          });
        }
      });
    });

    DirectoryProxy _getProxyForDir(PseudoDir dir, [int flags = 0]) {
      DirectoryProxy proxy = DirectoryProxy();
      var status = dir.connect(
          flags, 0, InterfaceRequest(proxy.ctrl.request().passChannel()));
      expect(status, ZX.OK);
      return proxy;
    }

    test('open passes', () async {
      PseudoDir dir = PseudoDir();
      DirectoryProxy proxy = _getProxyForDir(dir, openFlagDescribe);

      await proxy.onOpen.first.then((response) {
        expect(response.s, ZX.OK);
        expect(response.info, isNotNull);
      }).catchError((err) async {
        fail(err.toString());
      });
    });

    test('open passes with valid mode', () async {
      PseudoDir dir = PseudoDir();
      var validModes = [
        modeProtectionMask,
        modeTypeDirectory,
      ];

      var i = 0;
      for (var mode in validModes) {
        DirectoryProxy proxy = DirectoryProxy();
        var status = dir.connect(openFlagDescribe, mode,
            InterfaceRequest(proxy.ctrl.request().passChannel()));
        expect(status, ZX.OK, reason: 'modeIndex: $i');
        i++;
        await proxy.onOpen.first.then((response) {
          expect(response.s, ZX.OK);
          expect(response.info, isNotNull);
        }).catchError((err) async {
          fail(err.toString());
        });
      }
    });

    test('open passes with valid flags', () async {
      PseudoDir dir = PseudoDir();
      var validFlags = [
        openRightReadable,
        openRightWritable,
        openFlagDirectory,
        openFlagNodeReference
      ];

      for (var flag in validFlags) {
        DirectoryProxy proxy = _getProxyForDir(dir, flag | openFlagDescribe);
        await proxy.onOpen.first.then((response) {
          expect(response.s, ZX.OK);
          expect(response.info, isNotNull);
        }).catchError((err) async {
          fail(err.toString());
        });
      }
    });

    test('getattr', () async {
      PseudoDir dir = PseudoDir();
      DirectoryProxy proxy = _getProxyForDir(dir);

      var attr = await proxy.getAttr();

      expect(attr.attributes.linkCount, 1);
      expect(attr.attributes.mode, modeProtectionMask | modeTypeDirectory);
    });

    _Dirent _createDirentForDot() {
      return _Dirent(inoUnknown, 1, direntTypeDirectory, '.');
    }

    _Dirent _createDirent(Vnode vnode, String name) {
      return _Dirent(vnode.inodeNumber(), name.length, vnode.type(), name);
    }

    int _expectedDirentSize(List<_Dirent> dirents) {
      var sum = 0;
      for (var d in dirents) {
        sum += d.direntSizeInBytes;
      }
      return sum;
    }

    void _validateExpectedDirents(
        List<_Dirent> dirents, Directory$ReadDirents$Response response) {
      expect(response.s, ZX.OK);
      expect(response.dirents.length, _expectedDirentSize(dirents));
      var offset = 0;
      for (var dirent in dirents) {
        var data = ByteData.view(
            response.dirents.buffer, response.dirents.offsetInBytes + offset);
        var actualDirent = _Dirent.fromData(data);
        expect(actualDirent, dirent);
        offset += actualDirent.direntSizeInBytes;
      }
    }

    group('read dir:', () {
      test('simple call should work', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        var file2 = PseudoFile.readOnlyStr(() => 'file2');
        var file3 = PseudoFile.readOnlyStr(() => 'file3');
        dir
          ..addNode('file1', file1)
          ..addNode('subDir', subDir)
          ..addNode('file3', file3);
        subDir.addNode('file2', file2);

        DirectoryProxy proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
          _createDirent(file3, 'file3'),
        ];
        var response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);

        // test that next read call returns length zero buffer
        response = await proxy.readDirents(1024);
        expect(response.s, ZX.OK);
        expect(response.dirents.length, 0);

        // also test sub folder and make sure it was not affected by parent dir.
        proxy = _getProxyForDir(subDir);
        expectedDirents = [
          _createDirentForDot(),
          _createDirent(file2, 'file2'),
        ];
        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('serve function works', () async {
        PseudoDir dir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');

        dir.addNode('file1', file1);

        DirectoryProxy proxy = DirectoryProxy();
        var status =
            dir.serve(InterfaceRequest(proxy.ctrl.request().passChannel()));
        expect(status, ZX.OK);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
        ];
        var response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('passed buffer size is exact', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        var file3 = PseudoFile.readOnlyStr(() => 'file3');
        dir
          ..addNode('file1', file1)
          ..addNode('subDir', subDir)
          ..addNode('file3', file3);
        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
          _createDirent(file3, 'file3'),
        ];
        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        // test that next read call returns length zero buffer
        response = await proxy.readDirents(1024);
        expect(response.s, ZX.OK);
        expect(response.dirents.length, 0);
      });

      test('passed buffer size is exact - 1', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        var file3 = PseudoFile.readOnlyStr(() => 'file3');
        dir
          ..addNode('file1', file1)
          ..addNode('subDir', subDir)
          ..addNode('file3', file3);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
          _createDirent(file3, 'file3'),
        ];
        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) - 1);
        var lastDirent = expectedDirents.removeLast();
        _validateExpectedDirents(expectedDirents, response);

        // test that next read call returns last dirent
        response = await proxy.readDirents(1024);
        _validateExpectedDirents([lastDirent], response);

        // test that next read call returns length zero buffer
        response = await proxy.readDirents(1024);
        expect(response.s, ZX.OK);
        expect(response.dirents.length, 0);
      });

      test('buffer too small', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var size = _expectedDirentSize([_createDirentForDot()]) - 1;
        for (int i = 0; i < size; i++) {
          var response = await proxy.readDirents(i);
          expect(response.s, ZX.ERR_BUFFER_TOO_SMALL);
          expect(response.dirents.length, 0);
        }
      });

      test(
          'buffer too small after first dot read and subsequent reads with bigger buffer returns correct dirents',
          () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);
        var size = _expectedDirentSize([_createDirentForDot()]);
        var response = await proxy.readDirents(size);

        // make sure that '.' was read
        _validateExpectedDirents([_createDirentForDot()], response);

        // this should return error
        response = await proxy.readDirents(size);
        expect(response.s, ZX.ERR_BUFFER_TOO_SMALL);
        expect(response.dirents.length, 0);

        var expectedDirents = [
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
        ];
        response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);
      });

      test('multiple reads with small buffer', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);
        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
        ];
        for (var dirent in expectedDirents) {
          var dirents = [dirent];
          var response = await proxy.readDirents(_expectedDirentSize(dirents));
          _validateExpectedDirents(dirents, response);
        }

        // test that next read call returns length zero buffer
        var response = await proxy.readDirents(1024);
        expect(response.s, ZX.OK);
        expect(response.dirents.length, 0);
      });

      test('read two dirents then one', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        expectedDirents = [
          _createDirent(subDir, 'subDir'),
        ];

        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('buffer size more than first less than 2 dirents', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) + 10);
        _validateExpectedDirents(expectedDirents, response);

        // now test that we are able to get rest
        expectedDirents = [
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
        ];

        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('rewind works', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) + 10);
        _validateExpectedDirents(expectedDirents, response);

        var rewindResponse = await proxy.rewind();
        expect(rewindResponse, ZX.OK);

        response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) + 10);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('rewind works after we reach directory end', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) + 10);
        _validateExpectedDirents(expectedDirents, response);

        var rewindResponse = await proxy.rewind();
        expect(rewindResponse, ZX.OK);

        response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents) + 10);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('readdir works when node removed', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        // remove first node
        dir.removeNode('file1');
        expectedDirents = [_createDirent(subDir, 'subDir')];
        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('readdir works when already last node is removed', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1')
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        // remove first node
        dir.removeNode('file1');
        expectedDirents = [_createDirent(subDir, 'subDir')];
        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('readdir works when node is added', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir')
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        dir.addNode('file2', file1);
        expectedDirents = [_createDirent(file1, 'file2')];
        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });

      test('readdir works when node is added and only first node was read',
          () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);

        var expectedDirents = [
          _createDirentForDot(),
        ];

        var response =
            await proxy.readDirents(_expectedDirentSize(expectedDirents));
        _validateExpectedDirents(expectedDirents, response);

        dir.addNode('file2', file1);
        expectedDirents = [
          _createDirent(file1, 'file1'),
          _createDirent(subDir, 'subDir'),
          _createDirent(file1, 'file2')
        ];
        response = await proxy.readDirents(1024);
        _validateExpectedDirents(expectedDirents, response);
      });
    });

    group('open/close file/dir in dir:', () {
      Future<void> _openFileAndAssert(DirectoryProxy proxy, String filePath,
          int bufferLen, String expectedContent) async {
        FileProxy fileProxy = FileProxy();
        await proxy.open(openRightReadable, 0, filePath,
            InterfaceRequest(fileProxy.ctrl.request().passChannel()));

        var readResonse = await fileProxy.read(bufferLen);
        expect(readResonse.s, ZX.OK);
        expect(String.fromCharCodes(readResonse.data), expectedContent);
      }

      PseudoDir _setUpDir() {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        var file2 = PseudoFile.readOnlyStr(() => 'file2');
        var file3 = PseudoFile.readOnlyStr(() => 'file3');
        var file4 = PseudoFile.readOnlyStr(() => 'file4');
        dir
          ..addNode('file1', file1)
          ..addNode('subDir', subDir)
          ..addNode('file3', file3);
        subDir..addNode('file2', file2)..addNode('file4', file4);
        return dir;
      }

      test('open self', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);
        var paths = ['.', './', './/', './//', './/.//./'];
        for (var path in paths) {
          DirectoryProxy newProxy = DirectoryProxy();
          await proxy.open(0, 0, path,
              InterfaceRequest(newProxy.ctrl.request().passChannel()));

          // open file 1 in proxy and check contents to make sure correct dir was opened.
          await _openFileAndAssert(newProxy, 'file1', 100, 'file1');
        }
      });

      test('open file', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        // open file 1 check contents.
        var paths = ['file1', './file1', './/file1', './//file1'];
        for (var path in paths) {
          await _openFileAndAssert(proxy, path, 100, 'file1');
        }
      });

      test('open fails for empty path', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);
        var newProxy = DirectoryProxy();
        await proxy.open(openFlagDescribe, 0, '',
            InterfaceRequest(newProxy.ctrl.request().passChannel()));

        await newProxy.onOpen.first.then((response) {
          expect(response.s, isNot(ZX.OK));
          expect(response.info, isNull);
        }).catchError((err) async {
          fail(err.toString());
        });
      });

      test('open file fails for path ending with "/"', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        FileProxy fileProxy = FileProxy();
        await proxy.open(openRightReadable | openFlagDescribe, 0, 'file1/',
            InterfaceRequest(fileProxy.ctrl.request().passChannel()));

        await fileProxy.onOpen.first.then((response) {
          expect(response.s, ZX.ERR_NOT_DIR);
          expect(response.info, isNull);
        }).catchError((err) async {
          fail(err.toString());
        });
      });

      test('open file fails for invalid key', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        FileProxy fileProxy = FileProxy();
        await proxy.open(openRightReadable, 0, 'invalid',
            InterfaceRequest(fileProxy.ctrl.request().passChannel()));

        // channel should be closed
        fileProxy.ctrl.whenClosed.asStream().listen(expectAsync1((_) {}));
      });

      test('open fails for trying to open file within a file', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        FileProxy fileProxy = FileProxy();
        await proxy.open(openRightReadable | openFlagDescribe, 0, 'file1/file2',
            InterfaceRequest(fileProxy.ctrl.request().passChannel()));

        await fileProxy.onOpen.first.then((response) {
          expect(response.s, ZX.ERR_NOT_DIR);
          expect(response.info, isNull);
        }).catchError((err) async {
          fail(err.toString());
        });
      });

      test('close works', () async {
        PseudoDir dir = PseudoDir();
        PseudoDir subDir = PseudoDir();
        var file1 = PseudoFile.readOnlyStr(() => 'file1');
        dir..addNode('file1', file1)..addNode('subDir', subDir);

        var proxy = _getProxyForDir(dir);
        DirectoryProxy subDirProxy = DirectoryProxy();
        await proxy.open(0, 0, 'subDir',
            InterfaceRequest(subDirProxy.ctrl.request().passChannel()));

        FileProxy fileProxy = FileProxy();
        await proxy.open(0, 0, 'file1',
            InterfaceRequest(fileProxy.ctrl.request().passChannel()));
        dir.close();
        proxy.ctrl.whenClosed.asStream().listen(expectAsync1((_) {}));
        subDirProxy.ctrl.whenClosed.asStream().listen(expectAsync1((_) {}));
        fileProxy.ctrl.whenClosed.asStream().listen(expectAsync1((_) {}));
      });

      test('open sub dir', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        DirectoryProxy dirProxy = DirectoryProxy();
        await proxy.open(0, 0, 'subDir',
            InterfaceRequest(dirProxy.ctrl.request().passChannel()));

        // open file 2 check contents to make sure correct dir was opened.
        await _openFileAndAssert(dirProxy, 'file2', 100, 'file2');
      });

      test('open sub dir with "/" at end', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        DirectoryProxy dirProxy = DirectoryProxy();
        await proxy.open(0, 0, 'subDir/',
            InterfaceRequest(dirProxy.ctrl.request().passChannel()));

        // open file 2 check contents to make sure correct dir was opened.
        await _openFileAndAssert(dirProxy, 'file2', 100, 'file2');
      });

      test('directly open file in sub dir', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir);

        // open file 2 in subDir.
        await _openFileAndAssert(proxy, 'subDir/file2', 100, 'file2');
      });

      test('readdir fails for NodeReference', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir, openFlagNodeReference);

        var response = await proxy.readDirents(1024);
        expect(response.s, ZX.ERR_BAD_HANDLE);
      });

      test('able to open a file for NodeReference', () async {
        PseudoDir dir = _setUpDir();

        var proxy = _getProxyForDir(dir, openFlagNodeReference);

        // open file 2 in subDir.
        await _openFileAndAssert(proxy, 'subDir/file2', 100, 'file2');
      });
    });

    test('test clone', () async {
      PseudoDir dir = PseudoDir();

      var proxy = _getProxyForDir(dir, 0);

      DirectoryProxy newProxy = DirectoryProxy();
      await proxy.clone(openFlagDescribe,
          InterfaceRequest(newProxy.ctrl.request().passChannel()));

      await newProxy.onOpen.first.then((response) {
        expect(response.s, ZX.OK);
        expect(response.info, isNotNull);
      }).catchError((err) async {
        fail(err.toString());
      });
    });

    test('test clone fails for invalid flags', () async {
      PseudoDir dir = PseudoDir();

      var proxy = _getProxyForDir(dir, 0);

      DirectoryProxy newProxy = DirectoryProxy();
      await proxy.clone(openFlagTruncate | openFlagDescribe,
          InterfaceRequest(newProxy.ctrl.request().passChannel()));

      await newProxy.onOpen.first.then((response) {
        expect(response.s, isNot(ZX.OK));
        expect(response.info, isNull);
      }).catchError((err) async {
        fail(err.toString());
      });
    });
  });
}

class _Dirent {
  static const int _fixedSize = 10;
  int ino;
  int size;
  int type;
  String str;

  int direntSizeInBytes;
  _Dirent(this.ino, this.size, this.type, this.str) {
    direntSizeInBytes = _fixedSize + size;
  }

  _Dirent.fromData(ByteData data) {
    ino = data.getUint64(0, Endian.little);
    size = data.getUint8(8);
    type = data.getUint8(9);
    var offset = _fixedSize;
    List<int> charBytes = [];
    direntSizeInBytes = offset + size;
    expect(data.lengthInBytes, greaterThanOrEqualTo(direntSizeInBytes));
    for (int i = 0; i < size; i++) {
      charBytes.add(data.getUint8(offset++));
    }
    str = utf8.decode(charBytes);
  }

  @override
  int get hashCode =>
      ino.hashCode + size.hashCode + type.hashCode + str.hashCode;

  @override
  bool operator ==(Object o) {
    return o is _Dirent &&
        o.ino == ino &&
        o.size == size &&
        o.type == type &&
        o.str == str;
  }

  @override
  String toString() {
    return '[ino: $ino, size: $size, type: $type, str: $str]';
  }
}

class _TestVnode extends Vnode {
  String _val;
  _TestVnode([this._val = '']);

  @override
  int connect(int flags, int mode, InterfaceRequest<Node> request,
      [int parentFlags = -1]) {
    throw UnimplementedError();
  }

  @override
  int inodeNumber() {
    return inoUnknown;
  }

  @override
  int type() {
    return direntTypeUnknown;
  }

  String value() => _val;

  @override
  void close() {}
}
