/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

import React from 'react';
import Moment from 'moment';
import { Link } from 'react-router';
import CodeMirror from 'codemirror';
import 'codemirror/mode/sql/sql.js';
import 'codemirror/addon/runmode/runmode.js';

import UserStore from '../stores/UserStore';
import AdhocQueryActions from '../actions/AdhocQueryActions';

class QueryPreview extends React.Component {
  constructor (props) {
    super(props);
    this.state = {showDetail: false};
    this.toggleQueryDetails = this.toggleQueryDetails.bind(this);
    this.cancelQuery = this.cancelQuery.bind(this);
  }

	render () {
    let query = this.props;

    if (!query.userQuery) return null;

    // code below before the return prepares the data to render, turning out
    // crude properties to glazed, garnished ones e.g. formatting of query
    let codeTokens = [];

    CodeMirror
      .runMode(query.userQuery,
        'text/x-mysql', function (text, style) {
        // this method is called for every token and gives the
        // token and style class for it.
        codeTokens.push(<span className={'cm-' + style}>{text}</span>);
      });

    // figuring out the className for query status
    // TODO optimize this construct
    let statusTypes = {
      'EXECUTED': 'success',
      'SUCCESSFUL': 'success',
      'FAILED': 'danger',
      'CANCELED': 'danger',
      'CLOSED': 'warning',
      'QUEUED': 'info',
      'RUNNING': 'info'
    };

    let statusClass = 'label-' + statusTypes[query.status.status] ||
      'label-info';
    let handle = query.queryHandle.handleId;
    let executionTime = (query.finishTime - query.submissionTime) / (1000 * 60);
    let statusType = query.status.status === 'ERROR' ? 'Error: ' : 'Status: ';
    let seeResult = '';
    let statusMessage = query.status.status === 'SUCCESSFUL' ?
      query.status.statusMessage :
      query.status.errorMessage;

    if (query.status.status === 'SUCCESSFUL') {
      seeResult = (<Link to='result' params={{handle: handle}}
        className='btn btn-success btn-xs pull-right' style={{marginLeft: '5px'}}>
        See Result
      </Link>);
    }

    return (
      <section>
        <div className='panel panel-default'>
          <pre className='cm-s-default' style={{cursor: 'pointer',
            border: '0px', marginBottom: '0px'}}
            onClick={this.toggleQueryDetails}>

            {codeTokens}

            <label className={'pull-right label ' + statusClass}>
              {query.status.status}
            </label>

            {query.queryName && (
              <label className='pull-right label label-primary'
                style={{marginRight: '5px'}}>
                {query.queryName}
              </label>
            )}

          </pre>

          {this.state.showDetail && (
            <div className='panel-body' style={{borderTop: '1px solid #cccccc',
            paddingBottom: '0px'}} key={'preview' + handle}>
              <div className='row'>
                <div className='col-lg-4 col-sm-4'>
                  <span className='text-muted'>Handle </span>
                  <strong>{ query.queryHandle.handleId || 'Unknown'}</strong>
                </div>
                <div className='col-lg-4 col-sm-4'>
                  <span className='text-muted'>Name </span>
                  <strong>{ query.queryName || 'Not specified'}</strong>
                </div>
                <div className='col-lg-4 col-sm-4'>
                  <span className='text-muted'>Submitted </span>
                  <strong>
                    { Moment(query.submissionTime).format('Do MMM YY, hh:mm:ss a')}
                  </strong>
                </div>
                <div className='col-lg-4 col-sm-4'>
                  <span className='text-muted'>Execution time </span>
                  <strong>

                    { executionTime > 0 ?
                      Math.ceil(executionTime) +
                        (executionTime > 1 ? ' mins' : ' min') : 'Still running'
                    }
                  </strong>
                </div>
              </div>
              <div className='row'>
                <div
                  className={'alert alert-' + statusTypes[query.status.status]}
                  style={{marginBottom: '0px', padding: '5px 15px 5px 15px'}}>
                    <p>
                      <strong>{statusType}</strong>
                      {statusMessage || query.status.status}

                      {seeResult}

                      <Link to='query' query={{handle: query.queryHandle.handleId}}
                        className='pull-right'>
                        Edit Query
                      </Link>

                    </p>
                </div>
              </div>
            </div>
          )}
        </div>
      </section>
    );
  }

  toggleQueryDetails () {
    this.setState({ showDetail: !this.state.showDetail });
  }

  cancelQuery () {
    let secretToken = UserStore.getUserDetails().secretToken;
    let handle = this.props && this.props.queryHandle &&
      this.props.queryHandle.handleId;

    if (!handle) return;

    AdhocQueryActions.cancelQuery(secretToken, handle);
  }
}

QueryPreview.propTypes = {
  queryHandle: React.PropTypes.string
};

export default QueryPreview;
