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

// part of "common_patch.dart";

@patch
class _File {
  @patch
  @pragma("vm:external-name", "File_Exists")
  external static _exists(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_Create")
  external static _create(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_CreateLink")
  external static _createLink(
      _Namespace namespace, Uint8List rawPath, String target);
  @patch
  @pragma("vm:external-name", "File_LinkTarget")
  external static _linkTarget(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_Delete")
  external static _deleteNative(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_DeleteLink")
  external static _deleteLinkNative(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_Rename")
  external static _rename(
      _Namespace namespace, Uint8List oldPath, String newPath);
  @patch
  @pragma("vm:external-name", "File_RenameLink")
  external static _renameLink(
      _Namespace namespace, Uint8List oldPath, String newPath);
  @patch
  @pragma("vm:external-name", "File_Copy")
  external static _copy(
      _Namespace namespace, Uint8List oldPath, String newPath);
  @patch
  @pragma("vm:external-name", "File_LengthFromPath")
  external static _lengthFromPath(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_LastModified")
  external static _lastModified(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_SetLastModified")
  external static _setLastModified(
      _Namespace namespace, Uint8List rawPath, int millis);
  @patch
  @pragma("vm:external-name", "File_LastAccessed")
  external static _lastAccessed(_Namespace namespace, Uint8List rawPath);
  @patch
  @pragma("vm:external-name", "File_SetLastAccessed")
  external static _setLastAccessed(
      _Namespace namespace, Uint8List rawPath, int millis);
  @patch
  @pragma("vm:external-name", "File_Open")
  external static _open(_Namespace namespace, Uint8List rawPath, int mode);
  @patch
  @pragma("vm:external-name", "File_OpenStdio")
  external static int _openStdio(int fd);
}

@patch
class _RandomAccessFileOps {
  @patch
  factory _RandomAccessFileOps(int pointer) =>
      new _RandomAccessFileOpsImpl(pointer);
}

@pragma("vm:entry-point")
class _RandomAccessFileOpsImpl extends NativeFieldWrapperClass1
    implements _RandomAccessFileOps {
  _RandomAccessFileOpsImpl._();

  factory _RandomAccessFileOpsImpl(int pointer) =>
      new _RandomAccessFileOpsImpl._().._setPointer(pointer);

  @pragma("vm:external-name", "File_SetPointer")
  external void _setPointer(int pointer);
  @pragma("vm:external-name", "File_GetPointer")
  external int getPointer();
  @pragma("vm:external-name", "File_GetFD")
  external int get fd;
  @pragma("vm:external-name", "File_Close")
  external int close();
  @pragma("vm:external-name", "File_ReadByte")
  external readByte();
  @pragma("vm:external-name", "File_Read")
  external read(int bytes);
  @pragma("vm:external-name", "File_ReadInto")
  external readInto(List<int> buffer, int start, int? end);
  @pragma("vm:external-name", "File_WriteByte")
  external writeByte(int value);
  @pragma("vm:external-name", "File_WriteFrom")
  external writeFrom(List<int> buffer, int start, int? end);
  @pragma("vm:external-name", "File_Position")
  external position();
  @pragma("vm:external-name", "File_SetPosition")
  external setPosition(int position);
  @pragma("vm:external-name", "File_Truncate")
  external truncate(int length);
  @pragma("vm:external-name", "File_Length")
  external length();
  @pragma("vm:external-name", "File_Flush")
  external flush();
  @pragma("vm:external-name", "File_Lock")
  external lock(int lock, int start, int end);
}

class _WatcherPath {
  final int pathId;
  final String path;
  final int events;
  int count = 0;
  _WatcherPath(this.pathId, this.path, this.events);
}

@patch
abstract class _FileSystemWatcher {
  void _pathWatchedEnd();

  static int? _id;
  static final Map<int, _WatcherPath> _idMap = {};

  final String _path;
  final int _events;
  final bool _recursive;

  _WatcherPath? _watcherPath;

  final StreamController<FileSystemEvent> _broadcastController =
      new StreamController<FileSystemEvent>.broadcast();

  @patch
  static Stream<FileSystemEvent> _watch(
      String path, int events, bool recursive) {
    if (Platform.isLinux || Platform.isAndroid) {
      return new _InotifyFileSystemWatcher(path, events, recursive)._stream;
    }
    if (Platform.isWindows) {
      return new _Win32FileSystemWatcher(path, events, recursive)._stream;
    }
    if (Platform.isMacOS) {
      return new _FSEventStreamFileSystemWatcher(path, events, recursive)
          ._stream;
    }
    throw new FileSystemException(
        "File system watching is not supported on this platform");
  }

  _FileSystemWatcher._(this._path, this._events, this._recursive) {
    if (!isSupported) {
      throw new FileSystemException(
          "File system watching is not supported on this platform", _path);
    }
    _broadcastController
      ..onListen = _listen
      ..onCancel = _cancel;
  }

  Stream<FileSystemEvent> get _stream => _broadcastController.stream;

  void _listen() {
    if (_id == null) {
      try {
        _id = _initWatcher();
        _newWatcher();
      } on dynamic catch (e) {
        _broadcastController.addError(new FileSystemException(
            "Failed to initialize file system entity watcher", null, e));
        _broadcastController.close();
        return;
      }
    }
    var pathId;
    try {
      pathId =
          _watchPath(_id!, _Namespace._namespace, _path, _events, _recursive);
    } on dynamic catch (e) {
      _broadcastController
          .addError(new FileSystemException("Failed to watch path", _path, e));
      _broadcastController.close();
      return;
    }
    if (!_idMap.containsKey(pathId)) {
      _idMap[pathId] = new _WatcherPath(pathId, _path, _events);
    }
    _watcherPath = _idMap[pathId];
    _watcherPath!.count++;
    _pathWatched().pipe(_broadcastController);
  }

  void _cancel() {
    final watcherPath = _watcherPath;
    if (watcherPath != null) {
      assert(watcherPath.count > 0);
      watcherPath.count--;
      if (watcherPath.count == 0) {
        var pathId = watcherPath.pathId;
        // DirectoryWatchHandle(aka pathId) might be closed already initiated
        // by issueReadEvent for example. When that happens, appropriate closeEvent
        // will arrive to us and we will remove this pathId from _idMap. If that
        // happens we should not try to close it again as pathId is no
        // longer usable(the memory it points to might be released)
        if (_idMap.containsKey(pathId)) {
          _unwatchPath(_id!, pathId);
          _pathWatchedEnd();
          _idMap.remove(pathId);
        }
      }
      _watcherPath = null;
    }
    final id = _id;
    if (_idMap.isEmpty && id != null) {
      _closeWatcher(id);
      _doneWatcher();
      _id = null;
    }
  }

  // Called when (and after) a new watcher instance is created and available.
  void _newWatcher() {}
  // Called when a watcher is no longer needed.
  void _doneWatcher() {}
  // Called when a new path is being watched.
  Stream _pathWatched();
  // Called when a path is no longer being watched.
  void _donePathWatched() {}

  static _WatcherPath _pathFromPathId(int pathId) {
    return _idMap[pathId]!;
  }

  static Stream _listenOnSocket(int socketId, int id, int pathId) {
    final nativeSocket = _NativeSocket.watch(socketId);
    final rawSocket = _RawSocket(nativeSocket);
    return rawSocket.expand((event) {
      var stops = [];
      var events = [];
      var pair = {};
      if (event == RawSocketEvent.read) {
        String getPath(event) {
          var path = _pathFromPathId(event[4]).path;
          if (event[2] != null && event[2].isNotEmpty) {
            path += Platform.pathSeparator;
            path += event[2];
          }
          return path;
        }

        bool getIsDir(event) {
          if (Platform.isWindows) {
            // Windows does not get 'isDir' as part of the event.
            // Links should also be skipped.
            return FileSystemEntity.isDirectorySync(getPath(event)) &&
                !FileSystemEntity.isLinkSync(getPath(event));
          }
          return (event[0] & FileSystemEvent._isDir) != 0;
        }

        void add(id, event) {
          if ((event.type & _pathFromPathId(id).events) == 0) return;
          events.add([id, event]);
        }

        void rewriteMove(event, isDir) {
          if (event[3]) {
            add(event[4], new FileSystemCreateEvent._(getPath(event), isDir));
          } else {
            add(event[4], new FileSystemDeleteEvent._(getPath(event), false));
          }
        }

        int eventCount;
        do {
          eventCount = 0;
          for (var event in _readEvents(id, pathId)) {
            if (event == null) continue;
            eventCount++;
            int pathId = event[4];
            if (!_idMap.containsKey(pathId)) {
              // Path is no longer being wathed.
              continue;
            }
            bool isDir = getIsDir(event);
            var path = getPath(event);
            if ((event[0] & FileSystemEvent.create) != 0) {
              add(event[4], new FileSystemCreateEvent._(path, isDir));
            }
            if ((event[0] & FileSystemEvent.modify) != 0) {
              add(event[4], new FileSystemModifyEvent._(path, isDir, true));
            }
            if ((event[0] & FileSystemEvent._modifyAttributes) != 0) {
              add(event[4], new FileSystemModifyEvent._(path, isDir, false));
            }
            if ((event[0] & FileSystemEvent.move) != 0) {
              int link = event[1];
              if (link > 0) {
                pair.putIfAbsent(pathId, () => {});
                if (pair[pathId].containsKey(link)) {
                  add(
                      event[4],
                      new FileSystemMoveEvent._(
                          getPath(pair[pathId][link]), isDir, path));
                  pair[pathId].remove(link);
                } else {
                  pair[pathId][link] = event;
                }
              } else {
                rewriteMove(event, isDir);
              }
            }
            if ((event[0] & FileSystemEvent.delete) != 0) {
              add(event[4], new FileSystemDeleteEvent._(path, false));
            }
            if ((event[0] & FileSystemEvent._deleteSelf) != 0) {
              add(event[4], new FileSystemDeleteEvent._(path, false));
              // Signal done event.
              stops.add([event[4], null]);
            }
          }
        } while (eventCount > 0);
        // Be sure to clear this manually, as the sockets are not read through
        // the _NativeSocket interface.
        nativeSocket.available = 0;
        for (var map in pair.values) {
          for (var event in map.values) {
            rewriteMove(event, getIsDir(event));
          }
        }
      } else if (event == RawSocketEvent.closed) {
        // After this point we should not try to do anything with pathId as
        // the handle it represented is closed and gone now.
        if (_idMap.containsKey(pathId)) {
          _idMap.remove(pathId);
          if (_idMap.isEmpty && _id != null) {
            _closeWatcher(_id!);
            _id = null;
          }
        }
      } else if (event == RawSocketEvent.readClosed) {
        // If Directory watcher buffer overflows, it will send an readClosed event.
        // Normal closing will cancel stream subscription so that path is
        // no longer being watched, not present in _idMap.
        if (_idMap.containsKey(pathId)) {
          var path = _pathFromPathId(pathId).path;
          _idMap.remove(pathId);
          if (_idMap.isEmpty && _id != null) {
            _closeWatcher(_id!);
            _id = null;
          }
          throw FileSystemException(
              'Directory watcher closed unexpectedly', path);
        }
      } else {
        assert(false);
      }
      events.addAll(stops);
      return events;
    });
  }

  @patch
  @pragma("vm:external-name", "FileSystemWatcher_IsSupported")
  external static bool get isSupported;

  @pragma("vm:external-name", "FileSystemWatcher_InitWatcher")
  external static int _initWatcher();
  @pragma("vm:external-name", "FileSystemWatcher_CloseWatcher")
  external static void _closeWatcher(int id);

  @pragma("vm:external-name", "FileSystemWatcher_WatchPath")
  external static int _watchPath(
      int id, _Namespace namespace, String path, int events, bool recursive);
  @pragma("vm:external-name", "FileSystemWatcher_UnwatchPath")
  external static void _unwatchPath(int id, int path_id);
  @pragma("vm:external-name", "FileSystemWatcher_ReadEvents")
  external static List _readEvents(int id, int path_id);
  @pragma("vm:external-name", "FileSystemWatcher_GetSocketId")
  external static int _getSocketId(int id, int path_id);
}

class _InotifyFileSystemWatcher extends _FileSystemWatcher {
  static final Map<int, StreamController> _idMap = {};
  static late StreamSubscription _subscription;

  _InotifyFileSystemWatcher(path, events, recursive)
      : super._(path, events, recursive);

  void _newWatcher() {
    int id = _FileSystemWatcher._id!;
    _subscription =
        _FileSystemWatcher._listenOnSocket(id, id, 0).listen((event) {
      if (_idMap.containsKey(event[0])) {
        if (event[1] != null) {
          _idMap[event[0]]!.add(event[1]);
        } else {
          _idMap[event[0]]!.close();
        }
      }
    });
  }

  void _doneWatcher() {
    _subscription.cancel();
  }

  Stream _pathWatched() {
    var pathId = _watcherPath!.pathId;
    if (!_idMap.containsKey(pathId)) {
      _idMap[pathId] = new StreamController<FileSystemEvent>.broadcast();
    }
    return _idMap[pathId]!.stream;
  }

  void _pathWatchedEnd() {
    var pathId = _watcherPath!.pathId;
    if (!_idMap.containsKey(pathId)) return;
    _idMap[pathId]!.close();
    _idMap.remove(pathId);
  }
}

class _Win32FileSystemWatcher extends _FileSystemWatcher {
  late StreamSubscription _subscription;
  late StreamController _controller;

  _Win32FileSystemWatcher(path, events, recursive)
      : super._(path, events, recursive);

  Stream _pathWatched() {
    var pathId = _watcherPath!.pathId;
    _controller = new StreamController<FileSystemEvent>();
    _subscription =
        _FileSystemWatcher._listenOnSocket(pathId, 0, pathId).listen((event) {
      assert(event[0] == pathId);
      if (event[1] != null) {
        _controller.add(event[1]);
      } else {
        _controller.close();
      }
    });
    return _controller.stream;
  }

  void _pathWatchedEnd() {
    _subscription.cancel();
    _controller.close();
  }
}

class _FSEventStreamFileSystemWatcher extends _FileSystemWatcher {
  late StreamSubscription _subscription;
  late StreamController _controller;

  _FSEventStreamFileSystemWatcher(path, events, recursive)
      : super._(path, events, recursive);

  Stream _pathWatched() {
    var pathId = _watcherPath!.pathId;
    var socketId = _FileSystemWatcher._getSocketId(0, pathId);
    _controller = new StreamController<FileSystemEvent>();
    _subscription =
        _FileSystemWatcher._listenOnSocket(socketId, 0, pathId).listen((event) {
      if (event[1] != null) {
        _controller.add(event[1]);
      } else {
        _controller.close();
      }
    });
    return _controller.stream;
  }

  void _pathWatchedEnd() {
    _subscription.cancel();
    _controller.close();
  }
}

@pragma("vm:entry-point", "call")
Uint8List _makeUint8ListView(Uint8List source, int offsetInBytes, int length) {
  return new Uint8List.view(source.buffer, offsetInBytes, length);
}
