import AutoRequest from 'trc-client-core/src/components/AutoRequest';
import DataTree from 'trc-client-core/src/components/DataTree';
import ObjectTable from 'trc-client-core/src/components/ObjectTable';
import Loader from 'trc-client-core/src/components/Loader';
import Widget from 'trc-client-core/src/components/Widget';
import HumanFileSize from 'trc-client-core/src/utils/HumanFileSize';
import {connect} from 'react-redux';
import {fromJS} from 'immutable';
import moment from 'moment';
import {requestSiteInformation} from 'trc-client-core/src/admin/AdminDuck';
import {
    ADMIN_EXPORT_REGISTRATION_FETCH,
    ADMIN_EXPORT_REGISTRATION_ERROR
} from 'trc-client-core/src/constants/ActionTypes';


var AdminSiteInformation = React.createClass({
    displayName: 'AdminSiteInformation',
    getMemoryUsage(appMemory, osMemory) {
        const mem = (obj) => (key) => HumanFileSize(obj.get(key));
        const app = mem(appMemory);
        const os = mem(osMemory);

        var javaUsage = `${app('freeMemory')} / ${app('totalMemory')} (${app('maxMemory')})`;
        var systemUsage = `${os('freePhysicalMemorySize')} / ${os('totalPhysicalMemorySize')}`;
        return `Java: ${javaUsage}, System: ${systemUsage}`;
    },
    getCPUUsage(info) {
        const round = (key) => Math.round(info.get(key) * 100);

        return `Load: ${info.get('systemLoadAverage').toFixed(2)}, Process: ${round('processCpuLoad')}%, System: ${round('systemCpuLoad')}%`;
    },
    getUptime(uptime) {
        var time = moment.duration(uptime);
        var details = ['days', 'hours', 'minutes', 'seconds']
            .filter(ii => time.get(ii))
            .map(ii => {
                return time.get(ii) + ii[0];
            })
            .join(' ');

        return `Around ${time.humanize()} (${details})`;
    },
    render() {
        var {siteInformation} = this.props;
        if(!siteInformation) {
            return <Loader/>;
        }

        const {memoryInfo, runtimeInfo, applicationVersion, operatingSystemInfo} = siteInformation.toObject();
        const {systemProperties} = runtimeInfo.toObject();

        const inputArgs = runtimeInfo.get('inputArguments').map(ii => <pre>{ii}</pre>);

        return (
            <div>
                <h1>Site Information</h1>

                <ObjectTable data={{
                    'Application Version': applicationVersion,
                    'Memory Usage': this.getMemoryUsage(memoryInfo, operatingSystemInfo),
                    'Processor Usage': this.getCPUUsage(operatingSystemInfo),
                    'Hostname': runtimeInfo.get('name').split('@')[1],
                    'Uptime': this.getUptime(runtimeInfo.get('uptime')),
                    'Start Time': moment(new Date(runtimeInfo.get('startTime'))).format('YYYY-MM-DD HH:mm'),
                    'Operating System': `${systemProperties.get('os.name')} ${systemProperties.get('os.version')} (${systemProperties.get('os.arch')})`,
                    'Java Version': systemProperties.get('java.version'),
                    'Input Arguments': inputArgs
                }} />

                <Widget modifier="clear" className="margin-row2">
                    <DataTree data={this.props.siteInformation} />
                </Widget>
            </div>
        );
    }
});

const autoRequest = AutoRequest(
    ['location.query'],
    (props) => {
        props.dispatch(requestSiteInformation());
    }
);

const connectWithAdminData = connect(state => {
    return {
        siteInformation: state.admin.get('siteInformation'),
        fetching: state.async.get(ADMIN_EXPORT_REGISTRATION_FETCH),
        error: state.async.get(ADMIN_EXPORT_REGISTRATION_ERROR)
    }
});

export default connectWithAdminData(autoRequest(AdminSiteInformation));
