<commit_before>'use strict';

import 'source-map-support/register';
import Promise from 'es6-promises';
import http from 'http';
import express from 'express';
import RED from 'node-red';
import os from 'os';
import fs from 'fs';
import { DeviceManagerStore } from './device-manager';

// Listen port
const PORT = process.env.PORT || 8100;
const DEFAULT_PACKAGE_JSON = __dirname + '/../package.json';

export class CandyRed {
  constructor(packageJsonPath) {
    // Create an Express app
    this.app = express();
    // Create a server
    this.server = http.createServer(this.app);

    // Device Management
    this.deviceManagerStore = new DeviceManagerStore(RED);

    // path to package.json
    this.packageJsonPath = packageJsonPath;

    // Flow file name
    this.flowFile = 'flows_candy-red.json';
  }

  _migrateFlowFile(userDir) {
    return new Promise((resolve, reject) => {
      if (!this.flowFile) {
        return reject(new Error('Missing this.flowFile!'));
      }
      let newPath = `${userDir}/${this.flowFile}`;
      let oldPath = `${userDir}/flows_candy-red_${os.hostname()}.json`;
      fs.rename(oldPath, newPath, err => {
        if (err) {
          let oldPath = `${userDir}/flows_candy-box_${os.hostname()}.json`;
          fs.rename(oldPath, newPath, () => {
            RED.log.info(`[MIGRATED] ${oldPath} => ${newPath}`);
            resolve();
          });
        } else {
          RED.log.info(`[MIGRATED] ${oldPath} => ${newPath}`);
          resolve();
        }
      });
    });
  }

  start() {
    this.server.listen(PORT);
    this._setupExitHandler();
    return this._inspectBoardStatus(this.packageJsonPath).then(versions => {
      return new Promise((resolve, reject) => {
        // Create the settings object - see default settings.js file for other options
        let settings = this._createREDSettigngs(versions);
        // Flow File Name Spec. Change Migration
        this._migrateFlowFile(settings.userDir).then(() => {
          resolve([settings, versions]);
        }).catch(err => {
          reject(err);
        });
      });
    }).then(args => {
      let settings = args[0];
      let versions = args[1];

      // Initialise the runtime with a server and settings
      RED.init(this.server, settings);
      settings.version += ` [candy-red v${versions.candyRedv}]`;

      // Serve the http nodes from /api
      this.app.use(settings.httpNodeRoot, RED.httpNode);

      let flowFilePath = settings.userDir + '/' + this.flowFile;
      this.deviceManagerStore.deviceState.testIfUIisEnabled(flowFilePath).then(enabled => {
        if (enabled) {
          RED.log.info('[CANDY RED] Deploying Flow Editor UI...');
          // Add a simple route for static content served from 'public'
          this.app.use('/', express.static(__dirname + '/public'));
          if (settings.httpAdminRoot) {
            this.app.get('/', (_, res) => {
              res.redirect(settings.httpAdminRoot);
            });
          }
          // Serve the editor UI from /red
          this.app.use(settings.httpAdminRoot, RED.httpAdmin);
        }

        // Start the runtime
        RED.start().then(() => {
          RED.log.info(`Listen port=${PORT}`);
        });
      });
    });
  }

  _createCandyRedEditorTheme(deviceId) {
    let name = os.hostname();
    let longname = name;
    if (deviceId) {
      name = deviceId;
      longname = `${os.hostname()} (${name})`;
    }
    return {
      page: {
        title: 'CANDY RED@' + name,
        favicon: __dirname + '/public/images/candy-red.ico',
        css: __dirname + '/public/css/candy-red.css'
      },
      header: {
        title: ' ** ' + longname + ' **',
        image: __dirname + '/public/images/candy-red.png'
      },
      menu: {
        'menu-item-help': {
          label: 'Powered By Node-RED',
          url: 'http://nodered.org/docs'
        },
        'menu-item-keyboard-shortcuts': true
      }
    };
  }

  _createCandyBoxEditorTheme(deviceId) {
    let name = os.hostname();
    let longname = name;
    if (deviceId) {
      name = deviceId;
      longname = `${os.hostname()} (${name})`;
    }
    return {
      page: {
        title: 'CANDY BOX@' + name,
        favicon: __dirname + '/public/images/candy-box.ico',
        css: __dirname + '/public/css/candy-box.css'
      },
      header: {
        title: ' ** ' + longname + ' **',
        image: __dirname + '/public/images/candy-box.png'
      },
      menu: {
        'menu-item-help': {
          label: 'Powered By Node-RED',
          url: 'http://nodered.org/docs'
        },
        'menu-item-keyboard-shortcuts': true
      }
    };
  }

  _inspectBoardStatus(inputPackageJsonPath) {
    return Promise.all([
      this.deviceManagerStore.deviceState.testIfCANDYIoTInstalled(),
      this.deviceManagerStore.deviceState.testIfLTEPiInstalled()
    ]).then(results => {
      let candyIotv;
      let ltepiv;
      let deviceId;
      if (results[0]) {
        candyIotv = results[0][0];
        deviceId = results[0][0];
        this.editorTheme = this._createCandyBoxEditorTheme(deviceId);
      } else if (results[1]) {
        ltepiv = results[1][0];
        deviceId = results[1][1];
        this.editorTheme = this._createCandyRedEditorTheme(deviceId);
      } else {
        this.editorTheme = this._createCandyRedEditorTheme();
      }
      return new Promise((resolve, reject) => {
        fs.stat(inputPackageJsonPath, err => {
          if (err) {
            return reject(err);<commit_msg>Show deviceId in the default theme as well<commit_after>'use strict';

import 'source-map-support/register';
import Promise from 'es6-promises';
import http from 'http';
import express from 'express';
import RED from 'node-red';
import os from 'os';
import fs from 'fs';
import { DeviceManagerStore } from './device-manager';

// Listen port
const PORT = process.env.PORT || 8100;
const DEFAULT_PACKAGE_JSON = __dirname + '/../package.json';

export class CandyRed {
  constructor(packageJsonPath) {
    // Create an Express app
    this.app = express();
    // Create a server
    this.server = http.createServer(this.app);

    // Device Management
    this.deviceManagerStore = new DeviceManagerStore(RED);

    // path to package.json
    this.packageJsonPath = packageJsonPath;

    // Flow file name
    this.flowFile = 'flows_candy-red.json';
  }

  _migrateFlowFile(userDir) {
    return new Promise((resolve, reject) => {
      if (!this.flowFile) {
        return reject(new Error('Missing this.flowFile!'));
      }
      let newPath = `${userDir}/${this.flowFile}`;
      let oldPath = `${userDir}/flows_candy-red_${os.hostname()}.json`;
      fs.rename(oldPath, newPath, err => {
        if (err) {
          let oldPath = `${userDir}/flows_candy-box_${os.hostname()}.json`;
          fs.rename(oldPath, newPath, () => {
            RED.log.info(`[MIGRATED] ${oldPath} => ${newPath}`);
            resolve();
          });
        } else {
          RED.log.info(`[MIGRATED] ${oldPath} => ${newPath}`);
          resolve();
        }
      });
    });
  }

  start() {
    this.server.listen(PORT);
    this._setupExitHandler();
    return this._inspectBoardStatus(this.packageJsonPath).then(versions => {
      return new Promise((resolve, reject) => {
        // Create the settings object - see default settings.js file for other options
        let settings = this._createREDSettigngs(versions);
        // Flow File Name Spec. Change Migration
        this._migrateFlowFile(settings.userDir).then(() => {
          resolve([settings, versions]);
        }).catch(err => {
          reject(err);
        });
      });
    }).then(args => {
      let settings = args[0];
      let versions = args[1];

      // Initialise the runtime with a server and settings
      RED.init(this.server, settings);
      settings.version += ` [candy-red v${versions.candyRedv}]`;

      // Serve the http nodes from /api
      this.app.use(settings.httpNodeRoot, RED.httpNode);

      let flowFilePath = settings.userDir + '/' + this.flowFile;
      this.deviceManagerStore.deviceState.testIfUIisEnabled(flowFilePath).then(enabled => {
        if (enabled) {
          RED.log.info('[CANDY RED] Deploying Flow Editor UI...');
          // Add a simple route for static content served from 'public'
          this.app.use('/', express.static(__dirname + '/public'));
          if (settings.httpAdminRoot) {
            this.app.get('/', (_, res) => {
              res.redirect(settings.httpAdminRoot);
            });
          }
          // Serve the editor UI from /red
          this.app.use(settings.httpAdminRoot, RED.httpAdmin);
        }

        // Start the runtime
        RED.start().then(() => {
          RED.log.info(`Listen port=${PORT}`);
        });
      });
    });
  }

  _createCandyRedEditorTheme(deviceId) {
    let name = os.hostname();
    let longname = name;
    if (deviceId) {
      name = deviceId;
      longname = `${os.hostname()} (${name})`;
    }
    return {
      page: {
        title: 'CANDY RED@' + name,
        favicon: __dirname + '/public/images/candy-red.ico',
        css: __dirname + '/public/css/candy-red.css'
      },
      header: {
        title: ' ** ' + longname + ' **',
        image: __dirname + '/public/images/candy-red.png'
      },
      menu: {
        'menu-item-help': {
          label: 'Powered By Node-RED',
          url: 'http://nodered.org/docs'
        },
        'menu-item-keyboard-shortcuts': true
      }
    };
  }

  _createCandyBoxEditorTheme(deviceId) {
    let name = os.hostname();
    let longname = name;
    if (deviceId) {
      name = deviceId;
      longname = `${os.hostname()} (${name})`;
    }
    return {
      page: {
        title: 'CANDY BOX@' + name,
        favicon: __dirname + '/public/images/candy-box.ico',
        css: __dirname + '/public/css/candy-box.css'
      },
      header: {
        title: ' ** ' + longname + ' **',
        image: __dirname + '/public/images/candy-box.png'
      },
      menu: {
        'menu-item-help': {
          label: 'Powered By Node-RED',
          url: 'http://nodered.org/docs'
        },
        'menu-item-keyboard-shortcuts': true
      }
    };
  }

  _inspectBoardStatus(inputPackageJsonPath) {
    return Promise.all([
      this.deviceManagerStore.deviceState.testIfCANDYIoTInstalled(),
      this.deviceManagerStore.deviceState.testIfLTEPiInstalled()
    ]).then(results => {
      let candyIotv;
      let ltepiv;
      let deviceId;
      if (results[0][0]) {
        deviceId = results[0][0];
      }
      if (results[0][1]) {
        candyIotv = results[0][1];
        this.editorTheme = this._createCandyBoxEditorTheme(deviceId);
      } else if (results[1][1]) {
        ltepiv = results[1][1];
        this.editorTheme = this._createCandyRedEditorTheme(deviceId);
      } else {
        this.editorTheme = this._createCandyRedEditorTheme(deviceId);
      }
      return new Promise((resolve, reject) => {
        fs.stat(inputPackageJsonPath, err => {
          if (err) {
            return reject(err);
{'fraction_non_alphanumeric': 0.14981949458483754, 'fraction_numerical': 0.003249097472924188, 'mean_word_length': 2.2184141736857392, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1727831', 'n_tokens_mistral': 3453, 'n_tokens_neox': 3432, 'n_words': 688}