import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Bar from './Bar';
import './Terminal.css';
import ObjectInspector from 'react-object-inspector';

function handleLogging(method, addToOutput) {
  const old = console[method];
  console[method] = (...args) => {
    old(...args);
    const res = [...args].map((arg, i) => {
      switch (typeof arg) {
        case 'object':
          return <ObjectInspector data={arg} key={i} />;
        case 'function':
          return `${arg}`;
        default:
          return arg;
      }
    });
    addToOutput(res);
  };
}

class Terminal extends Component {
  static displayName='Terminal';

  static propTypes = {
    msg: PropTypes.string,
    color: PropTypes.string,
    prompt: PropTypes.string,
    barColor: PropTypes.string,
    backgroundColor: PropTypes.string,
    commands: PropTypes.objectOf(PropTypes.func),
    description: PropTypes.objectOf(PropTypes.string),
    watchConsoleLogging: PropTypes.bool,
  };

  state = {
    prompt: '>',
    summary: [],
    commands: {},
    description: {},
    watchConsoleLogging: false
  };

  componentDidMount = () => {
    const node = this.refs.com;
    node.focus();
    this.allCommands();
    this.setDescription();
    this.showMsg();

    if (this.props.watchConsoleLogging) {
      this.watchConsoleLogging();
    }
  };

  adder = (inp) => {
    let summary = this.state.summary;
    summary.push(inp);
    this.setState({ summary, });
  }

  watchConsoleLogging = () => {
    handleLogging('log', this.adder);
    handleLogging('warn', this.adder);
    handleLogging('error', this.adder);
    handleLogging('info', this.adder);
  }

  allCommands = () => {
    this.setState({
      commands: {
        'clear': this.clearScreen,
        'show': this.showMsg,
        'help': this.showHelp,
        ...this.props.commands
      }
    });
  }

  setDescription = () => {
    this.setState({
      description: {
        'clear': 'clear the screen',
        'show': 'show the msg',
        'help': 'list all the commands',
        ...this.props.description
      }
    })
  }

  clearScreen = () => {
    this.setState({
      summary: []
    });
  }

  showMsg = () => {
    this.adder(this.props.msg);
  }

  showHelp = () => {
    const options = Object.keys(this.state.commands);
    const description = this.state.description
    for (var option of options) {
      this.adder(`${option} - ${description[option]}`);
    }
  }

  handleChange = (e) => {
    if (e.key === "Enter") {
      var inputText = this.refs.com.value;
      var inputArray = inputText.split(' ');
      var input = inputArray[0];
      var arg = inputArray[1]; // Undefined for function call
      var command = this.state.commands[input];
      this.adder(this.state.prompt + " " + inputText);

      if (command === undefined) {
        this.adder("-bash:" + input + ": command not found");
      }

      else if (input === 'clear') {
        this.clearScreen();
      }

      else {
        this.adder(command(arg));
      }

      this.refs.com.value = "";
    }
  }

  render () {
    const inputStyles = { backgroundColor: this.props.backgroundColor, color: this.props.color };
    const prompt = { color: this.props.prompt };
    const barColor = { backgroundColor: this.props.barColor };
    const backgroundColor = { backgroundColor: this.props.backgroundColor }

    const output = this.state.summary.map((content, i) => {
      return (
        <div className="terminal-output-line" key={i}>{content}</div>
      );
    });

    return (
      <div className="terminal-container-wrapper" style={{ color: this.props.color, ...this.props.style }}>
        <Bar style={ barColor }/>
        <div className="terminal-container terminal-container-main" style={backgroundColor}>
          <div className="terminal-holder">
            <div className="terminal-content">
              <div className="terminal-input-area">
                {output}
                <p>
                  <span className="terminal-prompt" style={prompt}>{this.state.prompt}</span>
                  <input className="terminal-main-input" style={inputStyles} type="text" ref="com" onKeyPress={this.handleChange} />
                </p>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

}

export default Terminal;

@@ -176,16 +176,55 @@
 ctor';%0A%0A
+const oldConsoleLog = console%5B'log'%5D;%0A%0A
 function
@@ -265,39 +265,8 @@
 ) %7B%0A
-  const old = console%5Bmethod%5D;%0A
   co
@@ -303,17 +303,42 @@
 %0A    old
-(
+ConsoleLog(%60%5B$%7Bmethod%7D%5D%60, 
 ...args)
@@ -1573,32 +1573,71 @@
 ', this.adder);%0A
+    handleLogging('info', this.adder);%0A
     handleLoggin
@@ -1703,47 +1703,8 @@
 r);%0A
-    handleLogging('info', this.adder);%0A
   %7D%0A

fix chrome duplication of warn and error calls