// tslint:disable-next-line:max-line-length
import {apply, chain, filter, MergeStrategy, mergeWith, move, Rule, SchematicContext, template, Tree, url} from '@angular-devkit/schematics';
import {getWorkspace} from '@schematics/angular/utility/config';
import {getProjectFromWorkspace} from '@angular/cdk/schematics';
import {addPackageJsonDependency, NodeDependency, NodeDependencyType} from '@schematics/angular/utility/dependencies';
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
import {Schema} from './schema';

const dependencies: NodeDependency[] = [
  {
    type: NodeDependencyType.Default,
    version: '8.0.54',
    name: 'ng-yunzai-mobile'
  },
  {
    type: NodeDependencyType.Default,
    version: '^8.2.3',
    name: '@angular/material'
  },
  {
    type: NodeDependencyType.Default,
    version: '2.4.4',
    name: 'ngx-pinch-zoom'
  },
  {
    type: NodeDependencyType.Default,
    version: '^3.3.5',
    name: 'ngx-image-cropper'
  },
  {
    type: NodeDependencyType.Default,
    version: '^1.0.17',
    name: 'browser-image-compression'
  },
  {
    type: NodeDependencyType.Default,
    version: '^8.2.3',
    name: '@angular/cdk'
  }
];

export default function (options: Schema): Rule {
  return (tree: Tree, context: SchematicContext) => {
    return chain([
      // 生成依赖
      generatePackageToPackageJson(context),
      // 生成scripts sonar hooks
      generateScriptsSonarHooks(),
      // 删除
      removeOrginalFiles(options),
      // 创建
      addFiles(tree, context, options),
      // 下载所有包
      downLoadAllPackages(context)
    ]);
  };
}

export function generatePackageToPackageJson(context: SchematicContext): Rule {
  return (host: Tree) => {
    dependencies.forEach(dependency => {
      addPackageJsonDependency(host, dependency);
      context.logger.log('info', `️Added "${dependency.name}" into ${dependency.type}`);
    });
    return host;
  };
}

export function generateScriptsSonarHooks(): Rule {
  return (host: Tree) => {
    if (host.exists('package.json')) {
      // @ts-ignore
      const sourceText = host.read('package.json').toString('utf-8');
      const json = JSON.parse(sourceText);
      if (!json.scripts) {
        json.scripts = {};
      } else {
        json.scripts.lint = 'ng lint';
        json.scripts.fixcode = 'npm run lint --fix';
        json.scripts.build = 'ng build --prod';
      }
      host.overwrite('package.json', JSON.stringify(json, null, 2));
    }
    return host;
  };
}

export function downLoadAllPackages(context: SchematicContext): Rule {
  return (host: Tree) => {
    context.addTask(new NodePackageInstallTask());
    return host;
  };
}

function removeOrginalFiles(options: Schema) {
  return (host: Tree) => {
    const workspace = getWorkspace(host);
    const project = getProjectFromWorkspace(workspace, options.project);
    [
      `${project.sourceRoot}/environments/environment.prod.ts`,
      `${project.sourceRoot}/environments/environment.ts`,
      `${project.sourceRoot}/index.html`,
      `${project.sourceRoot}/app/app.module.ts`,
      `${project.sourceRoot}/app/app.component.ts`,
      `${project.sourceRoot}/app/app.component.html`,
      `${project.sourceRoot}/app/app.component.less`,
      `${project.sourceRoot}/app/index/index.component.html`,
      `${project.sourceRoot}/app/index/index.component.less`,
      `${project.sourceRoot}/app/index/index.component.ts`,
      `${project.sourceRoot}/app/app-routing.module.ts`,
      `${project.sourceRoot}/assets/imgs/icon_dept.png`,
      `${project.sourceRoot}/assets/imgs/icon_excel.png`,
      `${project.sourceRoot}/assets/imgs/icon_file.png`,
      `${project.sourceRoot}/assets/imgs/icon_img.png`,
      `${project.sourceRoot}/assets/imgs/icon_mp3.png`,
      `${project.sourceRoot}/assets/imgs/icon_mp4.png`,
      `${project.sourceRoot}/assets/imgs/icon_othert.png`,
      `${project.sourceRoot}/assets/imgs/icon_pdf.png`,
      `${project.sourceRoot}/assets/imgs/icon_ppt.png`,
      `${project.sourceRoot}/assets/imgs/icon_text.png`,
      `${project.sourceRoot}/assets/imgs/icon_word.png`,
      `${project.sourceRoot}/assets/imgs/zwsj.png`
    ]
      .filter(p => host.exists(p))
      .forEach(p => host.delete(p));
    return host;
  };
}

function addFiles(tree: Tree, context: SchematicContext, options: Schema) {
  const workspace = getWorkspace(tree);
  const project = getProjectFromWorkspace(workspace, options.project);
  return chain([
    () => context.logger.info('addFiles...'),
    mergeWith(
      // 这些文件要作为模板，替换变量后再移动
      apply(url('./files'), [
        filter(path => !path.startsWith('/src/assets/')),
        template({
          ...options
        }),
        move(project.root as string)
      ]),
      MergeStrategy.Overwrite
    ),
    // 这些文件，不作为模板，直接移动原文件（ eruda.js 文件内容中包含 <% 符号，会被当成变量处理，导致报错。）
    mergeWith(
      apply(url('./files'), [
        filter(path => path.startsWith('/src/assets/')),
        move(project.root as string)
      ]),
      MergeStrategy.Overwrite
    ),
  ]);
}
