
/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


'use strict';

var generators = require('yeoman-generator');
var user = require('../node_modules/yeoman-generator/lib/actions/user');

var config = {};
var userName;

module.exports = generators.Base.extend({
  _fistCharToUpper: function(string){
    return string.replace(/^./, string[0].toUpperCase());
  },
  prompting: {
    name: function(){
      var done = this.async();
      this.prompt({
        type: 'input',
        name: 'name',
        message: 'Your project name',
        default: this.config.get('name') // value set in .yo-rc.json
      }, function (answers) {
        // TODO check if this view already exist
        config.name = answers.name;
        done();
      }.bind(this));
    }
  },
  writing: {
    rcFiles: function(){
      if (!user.git.name()){
        userName = ['', '']
      }
      else {
        userName = user.git.name().split(' ');
      }
      this.fs.copy(this.templatePath('.bowerrc'), this.destinationPath(`${this.config.get('folder')}/${config.name}/.bowerrc`));
      this.fs.copy(this.templatePath('.gitignore'), this.destinationPath(`${this.config.get('folder')}/${config.name}/.gitignore`));
    },
    packageJson: function(){
      this.fs.copyTpl(
        this.templatePath('package.json'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/package.json`),
        { name: config.name, author: {name: user.git.name()} }
      );
    },
    bowerJson: function(){
      this.fs.copyTpl(
        this.templatePath('bower.json'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/bower.json`),
        { name: config.name, author: {name: user.git.name(), email: user.git.email()} }
      );
    },
    index: function(){
      this.fs.copyTpl(
        this.templatePath('src/index.html'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/src/index.html`),
        { name: config.name, fileName: this._fistCharToUpper(config.name), user: {firstname: userName[0]}}
      );
    },
    css: function(){
      this.fs.copyTpl(
        this.templatePath('src/css/dev.css'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/src/css/dev.css`),
        {fileName: this._fistCharToUpper(config.name)}
      );
    },
    scss: function(){
      this.fs.copyTpl(
        this.templatePath('src/sass/main.scss'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/src/sass/main.scss`),
        {fileName: this._fistCharToUpper(config.name)}
      );
    },
    mainJs: function(){
      this.fs.copyTpl(
        this.templatePath('src/js/main.js'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/src/js/main.js`),
        { name: config.name, fileName: this._fistCharToUpper(config.name) }
      );
    },
    image: function(){
      this.fs.copyTpl(
        this.templatePath('src/icons/README.md'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/src/icons/README.md`));
    },
    template: function(){
      this.fs.copy(this.templatePath('src/templates/users-list.tpl.html'), this.destinationPath(`${this.config.get('folder')}/${config.name}/src/templates/users-list.tpl.html`));
    },
    gulp: function(){
      this.fs.copyTpl(
        this.templatePath('gulp/*.js'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/gulp`),
        {name: config.name, fileName: this._fistCharToUpper(config.name)}
      );
      this.fs.copy(this.templatePath('gulpfile.js'), this.destinationPath(`${this.config.get('folder')}/${config.name}/gulpfile.js`));
    },
    karma: function(){
      this.fs.copy(
        this.templatePath('karma.conf.js'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/karma.conf.js`)
      );
    },
    spec: function(){
      this.fs.copyTpl(
        this.templatePath('spec/sample.test.js'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/spec/sample.test.js`),
        { name: config.name, user: {email: user.git.email(), firstname: userName[0], lastname: userName[1] } }
      );
    },
    lint: function(){
      this.fs.copy(
        this.templatePath('.eslintrc'),
        this.destinationPath(`${this.config.get('folder')}/${config.name}/.eslintrc`)
      );
    }
  },
  install: function(){
    var done = this.async();
    this.prompt({
      type: 'confirm',
      name: 'deps',
      message: 'Install dependecies?',
      default: false // value set in .yo-rc.json
    }, function (answers) {
      if(answers.deps){
        process.chdir(`${this.config.get('folder')}/${config.name}`);
        this.installDependencies();
      }
      done();
    }.bind(this));
  }
});
