<commit_before>##############################################################################
#
#    CoCalc: Collaborative Calculation in the Cloud
#
#    Copyright (C) 2016, Sagemath Inc.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

###
# Help Page
###

if global['BACKEND']  # set in ./render.coffee
    BASE_URL = require('smc-util/theme').DOMAIN_NAME
else
    # browser
    {BASE_URL} = require('./misc_page')

$ = window.$
misc = require('smc-util/misc')
{React, ReactDOM, redux, rtypes, rclass} = require('./app-framework')
{Well, Col, Row, Accordion, Panel, ProgressBar, Table} = require('react-bootstrap')
{Icon, Loading, Space, TimeAgo, UNIT, Footer} = require('./r_misc')
{HelpEmailLink, SiteName, SiteDescription, PolicyPricingPageUrl} = require('./customize')
{RECENT_TIMES, RECENT_TIMES_KEY} = require('smc-util/schema')
{COLORS, HELP_EMAIL, WIKI_URL, DOC_URL, TWITTER_HANDLE, LIVE_DEMO_REQUEST, SITE_NAME} = require('smc-util/theme')
{ComputeEnvironment} = require('./compute_environment')

# List item style
li_style = exports.li_style =
    lineHeight    : 'inherit'
    marginBottom  : '10px'

# improve understanding of large numbers
fmt_large = (num) ->
    num = parseInt(num)
    if localStorage.fmt_large
        return num.toLocaleString(undefined, {useGrouping:true, maximumSignificantDigits: 2})
    else
        return num.toLocaleString()
    #num += 31 * num + 7890
    # num.toLocaleString(undefined, {useGrouping:true, maximumSignificantDigits: 2})


HelpPageUsageSection = rclass
    reduxProps :
        server_stats :
            loading             : rtypes.bool.isRequired
            hub_servers         : rtypes.array
            time                : rtypes.object
            accounts            : rtypes.number
            projects            : rtypes.number
            accounts_created    : rtypes.object # {RECENT_TIMES.key → number, ...}
            projects_created    : rtypes.object # {RECENT_TIMES.key → number, ...}
            projects_edited     : rtypes.object # {RECENT_TIMES.key → number, ...}
            files_opened        : rtypes.object

    displayName : 'HelpPage-HelpPageUsageSection'

    getDefaultProps: ->
        loading : true

    number_of_active_users: ->
        if @props.hub_servers.length == 0
            0
        else
            (x.clients for x in @props.hub_servers).reduce((s,t) -> s+t)

    render_active_users_stats: ->
        if @props.loading
            <div> Live server stats <Loading /> </div>
        else
            n = @number_of_active_users()
            <div style={textAlign:'center'}>
                    Currently connected users
                <ProgressBar style={marginBottom:10}
                    now={Math.max(n / 12 , 45 / 8) }
                    label={"#{n} connected users"} />
            </div>

    render_active_projects_stats: ->
        n = @props.projects_edited?[RECENT_TIMES_KEY.active]
        <ProgressBar now={Math.max(n / 3, 60 / 2)} label={"#{n} projects being edited"} />

    timespan_keys: ->
        ['last_hour', 'last_day', 'last_week', 'last_month']

    recent_usage_stats_rows: ->
        stats = [
            ['Modified projects', @props.projects_edited],
            ['Created projects', @props.projects_created],
            ['Created accounts', @props.accounts_created]
        ]

        for stat in stats
            <tr key={stat[0]}>
                <th style={textAlign:'left'}>{stat[0]}</th>
                {
                    for k in @timespan_keys()
                        <td key={k}>
                            {fmt_large(stat[1]?[RECENT_TIMES_KEY[k]])}
                        </td>
                }
            </tr>

    render_filetype_stats_rows: ->
        stats = [
            ['Sage Worksheets',   'sagews'],
            ['Jupyter Notebooks', 'ipynb'],
            ['LaTeX Documents',   'tex'],
            ['Markdown Documents','md']
        ]
        #if DEBUG then console.log('@props.files_opened', @props.files_opened)
        for [name, ext] in stats
            <tr key={name}>
                <th style={textAlign:'left'}>{name}</th>
                {
                    for timespan in @timespan_keys()
                        k        = RECENT_TIMES_KEY[timespan]
                        total    = @props.files_opened?.total?[k]?[ext]    ? 0
                        #distinct = @props.files_opened?.distinct?[k]?[ext] ? 0
                        <td key={k}>
                            {fmt_large(total)}
                        </td>
                }
            </tr>

    render_recent_usage_stats: ->
        if @props.loading
            return
        <Table bordered condensed hover className='cc-help-stats-table'>
            <thead>
                <tr>
                    <th>past</th>
                    <th>hour</th>
                    <th>day</th>
                    <th>week</th>
                    <th>month</th>
                </tr>
            </thead>
            <tbody>
                {@recent_usage_stats_rows()}
                <tr><td colSpan={5}>&nbsp;</td></tr>
                <tr>
                    <th style={textAlign:'left'}>Edited files</th>
                    <td colSpan={4}>&nbsp;</td>
                </tr>
                {@render_filetype_stats_rows()}
            </tbody>
        </Table>

    render_historical_metrics: ->
        return  # disabled, due to being broken...
        <li key='usage_metrics' style={li_style}>
            <a target='_blank' href='https://cocalc.com/b97f6266-fe6f-4b40-bd88-9798994a04d1/raw/metrics/metrics.html'>
                <Icon name='area-chart' fixedWidth />Historical system metrics
            </a> &mdash; CPU usage, running projects and software instances, etc
        </li>

    render_when_updated: ->
        if @props.time
            <span style={fontSize: '9pt', marginLeft: '20px', color: '#666'}>
                updated <TimeAgo date={new Date(@props.time)} />
            </span>

    render: ->
        # TODO: I changed to the share link since the raw link is no longer support (XSS attacks).
        # Unfortunately, it *will* be stale until we improve how things work; the only workaround
        # is to sign into that project and manually edit something right now...
        <Col sm={12} md={6}>
            <h3>
                <Icon name='dashboard' /> Statistics
                {@render_when_updated()}
            </h3>
            <div>
                {@render_active_users_stats()}
                {### @render_active_projects_stats() ###}
                <div style={marginTop: 20, textAlign:'center'}>
                    Recent user activity
                </div>
                {@render_recent_usage_stats()}
                <Icon name='line-chart' fixedWidth />{' '}
                <a target='_blank' href='https://share.cocalc.com/share/7561f68d-3d97-4530-b97e-68af2fb4ed13/stats.html'>
                More data...
                </a>
                <br/>
                {@render_historical_metrics()}
            </div>
        </Col>


SUPPORT_LINKS =
    email_help :
        commercial: true
        bold : true<commit_msg>switch stats link back to not using share server, so always updated<commit_after>##############################################################################
#
#    CoCalc: Collaborative Calculation in the Cloud
#
#    Copyright (C) 2016, Sagemath Inc.
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

###
# Help Page
###

if global['BACKEND']  # set in ./render.coffee
    BASE_URL = require('smc-util/theme').DOMAIN_NAME
else
    # browser
    {BASE_URL} = require('./misc_page')

$ = window.$
misc = require('smc-util/misc')
{React, ReactDOM, redux, rtypes, rclass} = require('./app-framework')
{Well, Col, Row, Accordion, Panel, ProgressBar, Table} = require('react-bootstrap')
{Icon, Loading, Space, TimeAgo, UNIT, Footer} = require('./r_misc')
{HelpEmailLink, SiteName, SiteDescription, PolicyPricingPageUrl} = require('./customize')
{RECENT_TIMES, RECENT_TIMES_KEY} = require('smc-util/schema')
{COLORS, HELP_EMAIL, WIKI_URL, DOC_URL, TWITTER_HANDLE, LIVE_DEMO_REQUEST, SITE_NAME} = require('smc-util/theme')
{ComputeEnvironment} = require('./compute_environment')

# List item style
li_style = exports.li_style =
    lineHeight    : 'inherit'
    marginBottom  : '10px'

# improve understanding of large numbers
fmt_large = (num) ->
    num = parseInt(num)
    if localStorage.fmt_large
        return num.toLocaleString(undefined, {useGrouping:true, maximumSignificantDigits: 2})
    else
        return num.toLocaleString()
    #num += 31 * num + 7890
    # num.toLocaleString(undefined, {useGrouping:true, maximumSignificantDigits: 2})


HelpPageUsageSection = rclass
    reduxProps :
        server_stats :
            loading             : rtypes.bool.isRequired
            hub_servers         : rtypes.array
            time                : rtypes.object
            accounts            : rtypes.number
            projects            : rtypes.number
            accounts_created    : rtypes.object # {RECENT_TIMES.key → number, ...}
            projects_created    : rtypes.object # {RECENT_TIMES.key → number, ...}
            projects_edited     : rtypes.object # {RECENT_TIMES.key → number, ...}
            files_opened        : rtypes.object

    displayName : 'HelpPage-HelpPageUsageSection'

    getDefaultProps: ->
        loading : true

    number_of_active_users: ->
        if @props.hub_servers.length == 0
            0
        else
            (x.clients for x in @props.hub_servers).reduce((s,t) -> s+t)

    render_active_users_stats: ->
        if @props.loading
            <div> Live server stats <Loading /> </div>
        else
            n = @number_of_active_users()
            <div style={textAlign:'center'}>
                    Currently connected users
                <ProgressBar style={marginBottom:10}
                    now={Math.max(n / 12 , 45 / 8) }
                    label={"#{n} connected users"} />
            </div>

    render_active_projects_stats: ->
        n = @props.projects_edited?[RECENT_TIMES_KEY.active]
        <ProgressBar now={Math.max(n / 3, 60 / 2)} label={"#{n} projects being edited"} />

    timespan_keys: ->
        ['last_hour', 'last_day', 'last_week', 'last_month']

    recent_usage_stats_rows: ->
        stats = [
            ['Modified projects', @props.projects_edited],
            ['Created projects', @props.projects_created],
            ['Created accounts', @props.accounts_created]
        ]

        for stat in stats
            <tr key={stat[0]}>
                <th style={textAlign:'left'}>{stat[0]}</th>
                {
                    for k in @timespan_keys()
                        <td key={k}>
                            {fmt_large(stat[1]?[RECENT_TIMES_KEY[k]])}
                        </td>
                }
            </tr>

    render_filetype_stats_rows: ->
        stats = [
            ['Sage Worksheets',   'sagews'],
            ['Jupyter Notebooks', 'ipynb'],
            ['LaTeX Documents',   'tex'],
            ['Markdown Documents','md']
        ]
        #if DEBUG then console.log('@props.files_opened', @props.files_opened)
        for [name, ext] in stats
            <tr key={name}>
                <th style={textAlign:'left'}>{name}</th>
                {
                    for timespan in @timespan_keys()
                        k        = RECENT_TIMES_KEY[timespan]
                        total    = @props.files_opened?.total?[k]?[ext]    ? 0
                        #distinct = @props.files_opened?.distinct?[k]?[ext] ? 0
                        <td key={k}>
                            {fmt_large(total)}
                        </td>
                }
            </tr>

    render_recent_usage_stats: ->
        if @props.loading
            return
        <Table bordered condensed hover className='cc-help-stats-table'>
            <thead>
                <tr>
                    <th>past</th>
                    <th>hour</th>
                    <th>day</th>
                    <th>week</th>
                    <th>month</th>
                </tr>
            </thead>
            <tbody>
                {@recent_usage_stats_rows()}
                <tr><td colSpan={5}>&nbsp;</td></tr>
                <tr>
                    <th style={textAlign:'left'}>Edited files</th>
                    <td colSpan={4}>&nbsp;</td>
                </tr>
                {@render_filetype_stats_rows()}
            </tbody>
        </Table>

    render_historical_metrics: ->
        return  # disabled, due to being broken...
        <li key='usage_metrics' style={li_style}>
            <a target='_blank' href='https://cocalc.com/b97f6266-fe6f-4b40-bd88-9798994a04d1/raw/metrics/metrics.html'>
                <Icon name='area-chart' fixedWidth />Historical system metrics
            </a> &mdash; CPU usage, running projects and software instances, etc
        </li>

    render_when_updated: ->
        if @props.time
            <span style={fontSize: '9pt', marginLeft: '20px', color: '#666'}>
                updated <TimeAgo date={new Date(@props.time)} />
            </span>

    render: ->
        # TODO: I changed to the share link since the raw link is no longer support (XSS attacks).
        # Unfortunately, it *will* be stale until we improve how things work; the only workaround
        # is to sign into that project and manually edit something right now...
        <Col sm={12} md={6}>
            <h3>
                <Icon name='dashboard' /> Statistics
                {@render_when_updated()}
            </h3>
            <div>
                {@render_active_users_stats()}
                {### @render_active_projects_stats() ###}
                <div style={marginTop: 20, textAlign:'center'}>
                    Recent user activity
                </div>
                {@render_recent_usage_stats()}
                <Icon name='line-chart' fixedWidth />{' '}
                <a target='_blank' href='https://cocalc.com/7561f68d-3d97-4530-b97e-68af2fb4ed13/raw/stats.html'>
                More data...
                </a>
                <br/>
                {@render_historical_metrics()}
            </div>
        </Col>


SUPPORT_LINKS =
    email_help :
        commercial: true
        bold : true
{'fraction_non_alphanumeric': 0.13806254767353165, 'fraction_numerical': 0.011568777015001272, 'mean_word_length': 1.8496649157761276, 'pattern_counts': {'":': 0, '<': 141, '<?xml version=': 0, '>': 167, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5294540', 'n_tokens_mistral': 4677, 'n_tokens_neox': 4392, 'n_words': 1064}