import { SmartFile } from './classes.smartfile.js';
import * as plugins from './plugins.js';
import * as fs from './fs.js';


export interface IVirtualDirectoryConstructorOptions {
  mode: ''
}

/**
 * a virtual directory exposes a fs api
 */
export class VirtualDirectory {

  consstructor(options = {}) {

  }

  // STATIC
  public static async fromFsDirPath(pathArg: string): Promise<VirtualDirectory> {
    const newVirtualDir = new VirtualDirectory();
    newVirtualDir.addSmartfiles(await fs.fileTreeToObject(pathArg, '**/*'));
    return newVirtualDir;
  }

  public static async fromVirtualDirTransferableObject(
    virtualDirTransferableObjectArg: plugins.smartfileInterfaces.VirtualDirTransferableObject
  ): Promise<VirtualDirectory> {
    const newVirtualDir = new VirtualDirectory();
    for (const fileArg of virtualDirTransferableObjectArg.files) {
      newVirtualDir.addSmartfiles([SmartFile.enfoldFromJson(fileArg) as SmartFile]);
    }
    return newVirtualDir;
  }

  // INSTANCE
  public smartfileArray: SmartFile[] = [];

  constructor() {}

  public addSmartfiles(smartfileArrayArg: SmartFile[]) {
    this.smartfileArray = this.smartfileArray.concat(smartfileArrayArg);
  }

  public async getFileByPath(pathArg: string) {
    for (const smartfile of this.smartfileArray) {
      if (smartfile.path === pathArg) {
        return smartfile;
      }
    }
  }

  public async toVirtualDirTransferableObject(): Promise<plugins.smartfileInterfaces.VirtualDirTransferableObject> {
    return {
      files: this.smartfileArray.map((smartfileArg) => smartfileArg.foldToJson()),
    };
  }

  public async saveToDisk(dirArg: string) {
    console.log(`writing VirtualDirectory with ${this.smartfileArray.length} files to directory:
    --> ${dirArg}`);
    for (const smartfileArg of this.smartfileArray) {
      const filePath = await smartfileArg.writeToDir(dirArg);
      console.log(`wrote ${smartfileArg.relative} to
        --> ${filePath}`);
    }
  }

  public async shiftToSubdirectory(subDir: string): Promise<VirtualDirectory> {
    const newVirtualDir = new VirtualDirectory();
    for (const file of this.smartfileArray) {
      if (file.path.startsWith(subDir)) {
        const adjustedFilePath = plugins.path.relative(subDir, file.path);
        file.path = adjustedFilePath;
        newVirtualDir.addSmartfiles([file]);
      }
    }
    return newVirtualDir;
  }

  public async addVirtualDirectory(virtualDir: VirtualDirectory, newRoot: string): Promise<void> {
    for (const file of virtualDir.smartfileArray) {
      file.path = plugins.path.join(newRoot, file.path);
    }
    this.addSmartfiles(virtualDir.smartfileArray);
  }
}
