text: 'use strict';
  
  var os = require('os');
  var path = require('path');
  
  var fo = require('../../file-operations');
  
  var isWindows = (os.platform() === 'win32');
  
  function writeSymbolicLink(file, optResolver, onWritten) {
    if (!file.symlink) {
      return onWritten(new Error('Missing symlink property on symbolic vinyl'));
    }
  
    var isRelative = optResolver.resolve('relativeSymlinks', file);
    var flags = fo.getFlags({
      overwrite: optResolver.resolve('overwrite', file),
      append: optResolver.resolve('append', file),
    });
  
    if (!isWindows) {
      // On non-Windows, just use 'file'
      return createLinkWithType('file');
    }
  
    fo.reflectStat(file.symlink, file, onReflect);
  
    function onReflect(statErr) {
      if (statErr && statErr.code !== 'ENOENT') {
        return onWritten(statErr);
      }
  
      // This option provides a way to create a Junction instead of a
      // Directory symlink on Windows. This comes with the following caveats:
      // * NTFS Junctions cannot be relative.
      // * NTFS Junctions MUST be directories.
      // * NTFS Junctions must be on the same file system.
      // * Most products CANNOT detect a directory is a Junction:
      //    This has the side effect of possibly having a whole directory
      //    deleted when a product is deleting the Junction directory.
      //    For example, JetBrains product lines will delete the entire contents
      //    of the TARGET directory because the product does not realize it's
      //    a symlink as the JVM and Node return false for isSymlink.
  
      // This function is Windows only, so we don't need to check again
      var useJunctions = optResolver.resolve('useJunctions', file);
  
      var dirType = useJunctions ? 'junction' : 'dir';
      // Dangling links are always 'file'
      var type = !statErr && file.isDirectory() ? dirType : 'file';
  
      createLinkWithType(type);
    }
  
    function createLinkWithType(type) {
      // This is done after prepare() to use the adjusted file.base property
      if (isRelative && type !== 'junction') {
        file.symlink = path.relative(file.base, file.symlink);
      }
  
      var opts = {
        flags: flags,
        type: type,
      };
      fo.symlink(file.symlink, file.path, opts, onSymlink);
  
      function onSymlink(symlinkErr) {
        if (symlinkErr) {
          return onWritten(symlinkErr);
        }
  
        fo.reflectLinkStat(file.path, file, onWritten);
      }
    }
  }
  
  module.exports = writeSymbolicLink;
  