scala/ScalaBook/chapter-09/src/main/scala/scalabook/file/MemFile.scala

package scalabook.file

import path.Path

sealed trait MemFile extends VFile[MemFile] {
  protected def combined(
    memFS: MemFS,
    full: Path,
    endingSlash: Boolean
  ): MemFile =
    memFS.resolve(full) match {
      case Some(file) => file
      case None => if(endingSlash)
        memFS.newFolder(full)
      else
        memFS.newFile(full)
    }
}

class MemoryFile(memFS: MemFS, val path: Path)
      extends MemFile {
  private[this] var bytes = new Array[Byte](0)

  def exists = true
  def isFile = true
  def isFolder = false
  def children = Nil
  def childrenNames = Nil

  def /(that: String) =
    combined(memFS, this.path / that, that.endsWith("/"))

  def /(that: Path) =
    combined(memFS, this.path / that, false)

  def inputStream =
    Some(new java.io.ByteArrayInputStream(bytes))

  def outputStream =
    Some(new java.io.ByteArrayOutputStream {
      override def close = {
       super.close
       MemoryFile.this.bytes = this.toByteArray
      }
    })
}

class MemoryFolder(memFS: MemFS, val path: Path)
      extends MemFile {
  def exists = true
  def isFile = false
  def isFolder = true
  def inputStream = None
  def outputStream = None

  def children =
    memFS.cache.values.filter(_.path.isChildOf(path)).toList

  def childrenNames = children.map(_.name)

  def /(that: String) =
    combined(memFS, this.path / that, that.endsWith("/"))

  def /(that: Path) =
    combined(memFS, this.path / that, false)
}