import * as fs from 'fs';
import * as path from 'path';

export function writeToFile(path: string, str: string) {
  fs.writeFileSync(path, str);
}

/**
 * This method is specifically for updating a JSON file using the filesystem
 *
 * @remarks
 * If you are looking to update a JSON file in a tree, look for ./ast-utils#updateJsonInTree
 * @param path Path of the JSON file on the filesystem
 * @param callback Manipulation of the JSON data
 */
export function updateJsonFile(path: string, callback: (a: any) => any) {
  const json = readJsonFile(path);
  callback(json);
  writeToFile(path, JSON.stringify(json, null, 2));
}

export function addApp(apps: any[] | undefined, newApp: any): any[] {
  if (!apps) {
    apps = [];
  }
  apps.push(newApp);

  apps.sort((a: any, b: any) => {
    if (a.name === '$workspaceRoot') return 1;
    if (b.name === '$workspaceRoot') return -1;
    if (a.main && !b.main) return -1;
    if (!a.main && b.main) return 1;
    if (a.name > b.name) return 1;
    return -1;
  });

  return apps;
}

export function serializeJson(json: any): string {
  return `${JSON.stringify(json, null, 2)}\n`;
}

/**
 * This method is specifically for reading a JSON file from the filesystem
 *
 * @remarks
 * If you are looking to read a JSON file in a Tree, use ./ast-utils#readJsonInTree
 * @param path Path of the JSON file on the filesystem
 */
export function readJsonFile(path: string): any {
  return JSON.parse(fs.readFileSync(path, 'utf-8'));
}

export function readCliConfigFile(): any {
  return readJsonFile('.angular-cli.json');
}

export function copyFile(file: string, target: string) {
  const f = path.basename(file);
  const source = fs.createReadStream(file);
  const dest = fs.createWriteStream(path.resolve(target, f));
  source.pipe(dest);
  source.on('error', e => console.error(e));
}

function directoryExists(name) {
  try {
    return fs.statSync(name).isDirectory();
  } catch (e) {
    return false;
  }
}

export function createDirectory(name: string) {
  if (!directoryExists(name)) {
    fs.mkdirSync(name);
  }
}
