var OrLogViewer_1,__decorate=this&&this.__decorate||function(e,t,i,a){var o,r=arguments.length,l=r<3?t:null===a?a=Object.getOwnPropertyDescriptor(t,i):a;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,i,a);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(l=(r<3?o(l):r>3?o(t,i,l):o(t,i))||l);return r>3&&l&&Object.defineProperty(t,i,l),l},__awaiter=this&&this.__awaiter||function(e,t,i,a){return new(i||(i=Promise))(function(o,r){function l(e){try{n(a.next(e))}catch(e){r(e)}}function s(e){try{n(a.throw(e))}catch(e){r(e)}}function n(e){var t;e.done?o(e.value):((t=e.value)instanceof i?t:new i(function(e){e(t)})).then(l,s)}n((a=a.apply(e,t||[])).next())})};import{css as e,html as t,LitElement as i,unsafeCSS as a}from"lit";import{customElement as o,property as r,query as l}from"lit/decorators.js";import{i18next as s,translate as n}from"@openremote/or-translate";import*as d from"@openremote/model";import c,{DefaultColor2 as h,DefaultColor3 as g,Util as v}from"@openremote/core";import"@openremote/or-mwc-components/or-mwc-input";import"@openremote/or-components/or-panel";import p from"moment";import{showSnackbar as m}from"@openremote/or-mwc-components/or-mwc-snackbar";import{OrVaadinDateTimePicker as _}from"@openremote/or-vaadin-components/or-vaadin-date-time-picker";import{when as u}from"lit/directives/when.js";import{ifDefined as b}from"lit/directives/if-defined.js";import{parse as f}from"http-link-header";let tableStyle=require("@material/data-table/dist/mdc.data-table.css"),style=e`
    :host {
        --internal-or-log-viewer-background-color: var(--or-log-viewer-background-color, var(--or-app-color2, ${a(h)}));
        --internal-or-log-viewer-text-color: var(--or-log-viewer-text-color, var(--or-app-color3, ${a(g)}));
        --internal-or-log-viewer-controls-margin: var(--or-log-viewer-controls-margin, 0);
        
        display: block;                
    }
    
    :host([hidden]) {
        display: none;
    }
    
    #container {
        display: flex;
        min-width: 0;
        width: 100%;
        height: 100%;
        flex-direction: column;
    }
       
    #msg {
        height: 100%;
        width: 100%;
        justify-content: center;
        align-items: baseline;
        text-align: center;
    }
    
    #msg:not([hidden]) {
        display: flex;    
    }
    
    #controls {
        flex: 0;
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        align-items: baseline;
        margin: var(--internal-or-log-viewer-controls-margin);
        padding: 0 20px 20px 20px;
    }
    
    #controls > * {
        margin-top: 20px;
    }
    
    #time-controls {
        display: flex;
        align-items: baseline;
    }
    
    #live-button {
        margin-right: 40px;
    }
    
    #log-controls, #ending-controls, #page-controls {
        display: flex;
        max-width: 100%;
        align-items: baseline;
    }
    
    #ending-controls {
        margin: 0 10px;
    }
    
    #log-controls > *, #ending-controls > *, #page-controls > * {
        padding: 0 5px;
    }
        
    #page-controls[hidden] {
        visibility: hidden;
    }
    
    #ending-date {
        min-width: 0;
    }
    
    #table-container {
        height: 100%;
        overflow: auto;
    }
    
    #table {
        width: 100%;
        margin-bottom: 10px;
    }
    
    #table > table {
        width: 100%;
        table-layout: fixed;
    }
    
    #table th:not(.icon-cell), #table td:not(.icon-cell) {
        word-wrap: break-word;
        white-space: pre-wrap;
    }
`,OrLogViewer=OrLogViewer_1=class extends n(s)(i){constructor(){super(...arguments),this.live=!1,this._loading=!1,this._currentPage=1}static get styles(){return[e`${a(tableStyle)}`,style]}connectedCallback(){super.connectedCallback()}disconnectedCallback(){super.disconnectedCallback(),this._cleanup(),this._unsubscribeEvents()}shouldUpdate(e){return(e.has("level")||e.has("interval")||e.has("timestamp")||e.has("limit")||e.has("categories")||e.has("filter")||e.has("live"))&&!this.live&&(this._pageCount=void 0,this._currentPage=1,this._data=void 0),this.interval||(this.interval=OrLogViewer_1.DEFAULT_INTERVAL),!this.categories&&this.config&&this.config.initialCategories&&(this.categories=[...this.config.initialCategories]),void 0===this.filter&&this.config&&this.config.initialFilter&&(this.filter=this.config.initialFilter),this.level||(this.config&&this.config.initialLevel?this.level=this.config.initialLevel:this.level=OrLogViewer_1.DEFAULT_LEVEL),this.live||this.timestamp||(this.timestamp=new Date),this._data||this.live||this._loadData(),e.has("live")&&(this.live?this._subscribeEvents():this._unsubscribeEvents()),super.shouldUpdate(e)}render(){let e=this._loading,i=this.live,a=this.config&&this.config.hideCategories,o=this.config&&this.config.hideFilter,r=this.config&&this.config.hideLevel,l=this._getCategoryMenuItems(),n=l.filter(e=>{var t;return null==(t=this.categories)?void 0:t.includes(e.value)});return t`
            <div id="container">
                <div id="controls">
                    <div id="log-controls">
                        ${u(!a,()=>t`
                            <or-vaadin-multi-select-combo-box .items=${l} .selectedItems=${n} style="width: 240px;"
                                                              @change=${e=>{let t=e.currentTarget;this._onCategoriesChanged(t.selectedItems.map(e=>e.value))}}>
                                <or-translate slot="label" value="categories"></or-translate>
                            </or-vaadin-multi-select-combo-box>
                        `)}
                        <!-- Filter by subcategory string -->
                        <or-vaadin-text-field id="subcategory-field" ?hidden=${o} ?disabled=${e} value=${this.filter} style="width: 200px;"
                                              @change=${e=>this._onFilterChanged(e)}>
                            <or-translate slot="label" value="subCategoryFilters"></or-translate>
                            <or-icon slot="suffix" icon="magnify"></or-icon>
                        </or-vaadin-text-field>
                        
                        <!-- Filter by log level -->
                        <or-vaadin-select id="level-select" ?hidden=${r} ?disabled=${e} value=${this.level} .items=${this._getLevelOptions()} style="width: 120px;"
                                          @change=${e=>this._onLevelChanged(e.currentTarget.value)}>
                            <or-translate slot="label" value="level"></or-translate>
                        </or-vaadin-select>
                        
                        <!-- Limit select -->
                        <or-vaadin-select id="limit-select" ?disabled=${e} value=${this.getLimit().toString()} .items=${this._getLimitOptions()} style="width: 80px;"
                                          @change=${e=>this._onLimitChanged(e.currentTarget.value)}>
                            <or-translate slot="label" value="limit"></or-translate>
                        </or-vaadin-select>
                    </div>
                    
                    <div id="page-controls" ?hidden="${i||!this._pageCount||!this._data||0===this._data.length}">
                        <or-vaadin-button theme="icon" ?disabled=${e||i||1===this._currentPage}
                                          @click=${()=>this._updatePage(!1)}>
                            <or-icon icon="chevron-left"></or-icon>
                        </or-vaadin-button>
                        <span>${this._currentPage}</span><or-translate value="of"></or-translate><span>${this._pageCount}</span>
                        <or-vaadin-button theme="icon" ?disabled=${e||i||this._currentPage===this._pageCount||this._data&&this._data.length<this.getLimit()}
                                          @click=${()=>this._updatePage(!0)}>
                            <or-icon icon="chevron-right"></or-icon>
                        </or-vaadin-button>
                    </div>
                    
                    <div id="time-controls">
                        <!-- Live logging on/off toggle -->
                        <or-vaadin-checkbox id="live-button" ?disabled=${e} ?checked=${this.live}
                                            @change=${e=>this._onLiveChanged(e.currentTarget.checked)}>
                            <label slot="label"><or-translate value="live"></or-translate></label>
                        </or-vaadin-checkbox>
                        <!-- Period select -->
                        <or-vaadin-select id="period-select" ?disabled=${e||i} value=${this.interval} .items=${this._getIntervalOptions()} style="min-width: 120px;"
                                          @change=${e=>this.interval=e.currentTarget.value}>
                            <or-translate slot="label" value="period"></or-translate>
                        </or-vaadin-select>
                        
                        <div id="ending-controls">
                            <or-vaadin-button theme="icon" ?disabled=${e||i} @click=${()=>this.timestamp=this._calculateTimestamp(this.timestamp,!1)}>
                                <or-icon icon="chevron-left"></or-icon>
                            </or-vaadin-button>
                            <or-vaadin-date-time-picker id="ending-date" ?disabled=${e||i} style="width: 280px; align-items: end;"
                                                        value=${b(_.getLocalizedISOString(this.timestamp))}
                                                        @change=${e=>this.timestamp=this._calculateTimestamp(p(e.currentTarget.value).toDate())}>
                                <or-translate slot="label" value="ending"></or-translate>
                            </or-vaadin-date-time-picker>
                            <or-vaadin-button theme="icon" ?disabled=${e||i}@click=${()=>this.timestamp=this._calculateTimestamp(this.timestamp,!0)}>
                                <or-icon icon="chevron-right"></or-icon>
                            </or-vaadin-button>
                            <or-vaadin-button theme="icon" ?disabled=${e||i} @click=${()=>this.timestamp=this._calculateTimestamp(new Date)}>
                                <or-icon icon="chevron-double-right"></or-icon>
                            </or-vaadin-button>
                        </div>
                    </div>
                </div>
                
                ${e?t`<div id="msg">${s.t("loading")}</div>`:t`<div id="table-container">
                        ${this._data?this._getTable():""}
                    </div>`}
            </div>
        `}_getLimitOptions(){return["25","50","100","200"].map(e=>({value:e,label:e}))}_getLevelOptions(){return Object.keys(d.SyslogLevel).map(e=>({value:e,label:s.t(e.toLocaleLowerCase())}))}_getCategoryMenuItems(){return(this.config&&this.config.allowedCategories?this.config.allowedCategories:Object.keys(d.SyslogCategory)).map(e=>({value:e,label:s.t("logCategory."+e,{defaultValue:v.capitaliseFirstLetter(e.toLowerCase().replace(/_/g," "))})}))}getLimit(){return this.limit||OrLogViewer_1.DEFAULT_LIMIT}_onCategoriesChanged(e){this.categories=e,this.categories&&this.live&&(this._data=this._data.filter(e=>this.categories.find(t=>t===e.category)))}_onLiveChanged(e){this.live=e,e&&(this._data=[],this._pageCount=void 0,this._currentPage=1)}_onLimitChanged(e){if(!e){this.limit=void 0;return}this.limit=parseInt(e);let t=this.getLimit();this.live&&this._data.length>t&&this._data.splice(t-1)}_onFilterChanged(e){let t=e.currentTarget;if(t.checkValidity()&&(this.filter=t.value,this.filter&&this.live)){let e=this.filter.split(";");this._data=this._data.filter(t=>e.find(e=>e===t.subCategory))}}_onLevelChanged(e){this.level=e,this.level&&this.live&&(this._data=this._data.filter(e=>this._eventMatchesLevel(e)))}_getTable(){return t`
            <div id="table" class="mdc-data-table">
                <table class="mdc-data-table__table" aria-label="logs list">
                    <thead>
                        <tr class="mdc-data-table__header-row">
                            <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${s.t("timestamp")}</th>
                            <th style="width: 80px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${s.t("level")}</th>
                            <th style="width: 130px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${s.t("category")}</th>
                            <th style="width: 180px" class="mdc-data-table__header-cell" role="columnheader" scope="col">${s.t("subCategory")}</th>
                            <th style="width: 100%; min-width: 300px;" class="mdc-data-table__header-cell" role="columnheader" scope="col">${s.t("message")}</th>
                            <th style="width: 80px;" class="mdc-data-table__header-cell" role="columnheader" scope="col"></th>
                        </tr>
                    </thead>
                    <tbody class="mdc-data-table__content">
                        ${this._data.map(e=>t`
                                <tr class="mdc-data-table__row">
                                    <td class="mdc-data-table__cell">${p(e.timestamp).format(OrLogViewer_1.DEFAULT_TIMESTAMP_FORMAT)}</td>
                                    <td class="mdc-data-table__cell">${s.t(e.level)}</td>
                                    <td class="mdc-data-table__cell">${s.t(e.category)}</td>                                    
                                    <td class="mdc-data-table__cell">${s.t(e.subCategory)}</td>
                                    <td class="mdc-data-table__cell">${e.message}</td>
                                    <td class="mdc-data-table__cell icon-cell">
                                        ${u(window.isSecureContext,()=>t`
                                            <or-vaadin-button class="copy-button" theme="icon" @click=${()=>this._copyRow(e)}>
                                                <or-icon icon="content-copy"></or-icon>
                                            </or-vaadin-button>
                                        `)}
                                    </td>
                                </tr>
                            `)}
                    </tbody>
                </table>
            </div>
            `}_copyRow(e){return __awaiter(this,void 0,void 0,function*(){try{let t=e.message||"";yield navigator.clipboard.writeText(t),m(void 0,s.t("copiedToClipboard"))}catch(e){console.error("Failed to copy:",e)}})}_getIntervalOptions(){return["HOUR","DAY","WEEK","MONTH","YEAR"].map(e=>({value:e,label:s.t(e.toLowerCase())}))}_loadData(){return __awaiter(this,void 0,void 0,function*(){if(this._loading)return;this._loading=!0;let e=yield c.rest.api.SyslogResource.getEvents({level:this.level,per_page:this.getLimit(),page:this._currentPage,from:this._getFrom(),to:this.timestamp?this.timestamp.getTime():void 0,category:this.categories,subCategory:this.filter?this.filter.split(";"):void 0});this._loading=!1,200===e.status&&(this._data=e.data,this._pageCount=this._getPageCount(e))})}_getPageCount(e){let t=e.headers.link;if(t){let e=f(t).rel("last");if(Array.isArray(e)&&e.length>0&&(e=e[0]),e&&e.uri){let t=new URL(e.uri);return parseInt(v.getQueryParameters(t.search).page)}}}_updatePage(e){this._pageCount&&(e?this._currentPage<this._pageCount&&(this._data=void 0,this._currentPage++):this._currentPage>1&&(this._data=void 0,this._currentPage--))}_subscribeEvents(){return __awaiter(this,void 0,void 0,function*(){c.events&&(this._eventSubscriptionId=yield c.events.subscribe({eventType:"syslog"},e=>this._onEvent(e)))})}_unsubscribeEvents(){this._eventSubscriptionId&&(c.events.unsubscribe(this._eventSubscriptionId),this._eventSubscriptionId=void 0)}_getFrom(){if(this.timestamp&&this.interval)return this._calculateTimestamp(this.timestamp,!1).getTime()}_calculateTimestamp(e,t){if(!this.interval)return;let i=p(e);if(void 0!==t)switch(this.interval){case"HOUR":i.add(t?1:-1,"hour");break;case"DAY":i.add(t?1:-1,"day");break;case"WEEK":i.add(t?1:-1,"week");break;case"MONTH":i.add(t?1:-1,"month");break;case"YEAR":i.add(t?1:-1,"year")}return i.toDate()}_onEvent(e){if(this.categories&&!this.categories.find(t=>t===e.category)||this.filter&&!this.filter.split(";").find(t=>t===e.subCategory)||!this._eventMatchesLevel(e))return;let t=this.getLimit();this._data.length===t-1&&this._data.pop(),this._data.splice(0,0,e),this._refresh&&window.clearTimeout(this._refresh),this._refresh=window.setTimeout(()=>this.requestUpdate("_data"),2e3)}_eventMatchesLevel(e){return!this.level||"INFO"===this.level||"WARN"===this.level&&("WARN"===e.level||"ERROR"===e.level)||"ERROR"===this.level&&"ERROR"===e.level}_cleanup(){this._table&&(this._table.destroy(),this._table=void 0),this._refresh&&window.clearTimeout(this._refresh)}};OrLogViewer.DEFAULT_TIMESTAMP_FORMAT="L HH:mm:ss",OrLogViewer.DEFAULT_LIMIT=50,OrLogViewer.DEFAULT_LEVEL="INFO",OrLogViewer.DEFAULT_INTERVAL="HOUR",__decorate([r({type:String})],OrLogViewer.prototype,"interval",void 0),__decorate([r({type:Number})],OrLogViewer.prototype,"timestamp",void 0),__decorate([r({type:Number})],OrLogViewer.prototype,"limit",void 0),__decorate([r({type:Array})],OrLogViewer.prototype,"categories",void 0),__decorate([r({type:String})],OrLogViewer.prototype,"filter",void 0),__decorate([r({type:String})],OrLogViewer.prototype,"level",void 0),__decorate([r({type:Boolean})],OrLogViewer.prototype,"live",void 0),__decorate([r({type:Object})],OrLogViewer.prototype,"config",void 0),__decorate([r()],OrLogViewer.prototype,"_loading",void 0),__decorate([r()],OrLogViewer.prototype,"_data",void 0),__decorate([l("#table")],OrLogViewer.prototype,"_tableElem",void 0),OrLogViewer=OrLogViewer_1=__decorate([o("or-log-viewer")],OrLogViewer);export{OrLogViewer};