/**
 * @license
 * Copyright 2018-2021 Streamlit Inc.
 *
 * Licensed 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 { Table, Type } from "apache-arrow";
var ArrowTable = /** @class */ (function () {
    function ArrowTable(dataBuffer, indexBuffer, columnsBuffer, styler) {
        var _this = this;
        this.getCell = function (rowIndex, columnIndex) {
            var isBlankCell = rowIndex < _this.headerRows && columnIndex < _this.headerColumns;
            var isIndexCell = rowIndex >= _this.headerRows && columnIndex < _this.headerColumns;
            var isColumnsCell = rowIndex < _this.headerRows && columnIndex >= _this.headerColumns;
            if (isBlankCell) {
                var classNames = ["blank"];
                if (columnIndex > 0) {
                    classNames.push("level" + rowIndex);
                }
                return {
                    type: "blank",
                    classNames: classNames.join(" "),
                    content: ""
                };
            }
            else if (isColumnsCell) {
                var dataColumnIndex = columnIndex - _this.headerColumns;
                var classNames = [
                    "col_heading",
                    "level" + rowIndex,
                    "col" + dataColumnIndex
                ];
                return {
                    type: "columns",
                    classNames: classNames.join(" "),
                    content: _this.getContent(_this.columnsTable, dataColumnIndex, rowIndex)
                };
            }
            else if (isIndexCell) {
                var dataRowIndex = rowIndex - _this.headerRows;
                var classNames = [
                    "row_heading",
                    "level" + columnIndex,
                    "row" + dataRowIndex
                ];
                return {
                    type: "index",
                    id: "T_" + _this.uuid + "level" + columnIndex + "_row" + dataRowIndex,
                    classNames: classNames.join(" "),
                    content: _this.getContent(_this.indexTable, dataRowIndex, columnIndex)
                };
            }
            else {
                var dataRowIndex = rowIndex - _this.headerRows;
                var dataColumnIndex = columnIndex - _this.headerColumns;
                var classNames = [
                    "data",
                    "row" + dataRowIndex,
                    "col" + dataColumnIndex
                ];
                var content = _this.styler
                    ? _this.getContent(_this.styler.displayValuesTable, dataRowIndex, dataColumnIndex)
                    : _this.getContent(_this.dataTable, dataRowIndex, dataColumnIndex);
                return {
                    type: "data",
                    id: "T_" + _this.uuid + "row" + dataRowIndex + "_col" + dataColumnIndex,
                    classNames: classNames.join(" "),
                    content: content
                };
            }
        };
        this.getContent = function (table, rowIndex, columnIndex) {
            var column = table.getColumnAt(columnIndex);
            if (column === null) {
                return "";
            }
            var columnTypeId = _this.getColumnTypeId(table, columnIndex);
            switch (columnTypeId) {
                case Type.Timestamp: {
                    return _this.nanosToDate(column.get(rowIndex));
                }
                default: {
                    return column.get(rowIndex);
                }
            }
        };
        this.dataTable = Table.from(dataBuffer);
        this.indexTable = Table.from(indexBuffer);
        this.columnsTable = Table.from(columnsBuffer);
        this.styler = styler
            ? {
                caption: styler.caption,
                displayValuesTable: Table.from(styler.displayValues),
                styles: styler.styles,
                uuid: styler.uuid
            }
            : undefined;
    }
    Object.defineProperty(ArrowTable.prototype, "rows", {
        get: function () {
            return this.indexTable.length + this.columnsTable.numCols;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "columns", {
        get: function () {
            return this.indexTable.numCols + this.columnsTable.length;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "headerRows", {
        get: function () {
            return this.rows - this.dataRows;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "headerColumns", {
        get: function () {
            return this.columns - this.dataColumns;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "dataRows", {
        get: function () {
            return this.dataTable.length;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "dataColumns", {
        get: function () {
            return this.dataTable.numCols;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "uuid", {
        get: function () {
            return this.styler && this.styler.uuid;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "caption", {
        get: function () {
            return this.styler && this.styler.caption;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "styles", {
        get: function () {
            return this.styler && this.styler.styles;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "table", {
        get: function () {
            return this.dataTable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "index", {
        get: function () {
            return this.indexTable;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(ArrowTable.prototype, "columnTable", {
        get: function () {
            return this.columnsTable;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Serialize arrow table.
     */
    ArrowTable.prototype.serialize = function () {
        return {
            data: this.dataTable.serialize(),
            index: this.indexTable.serialize(),
            columns: this.columnsTable.serialize()
        };
    };
    /**
     * Returns apache-arrow specific typeId of column.
     */
    ArrowTable.prototype.getColumnTypeId = function (table, columnIndex) {
        return table.schema.fields[columnIndex].type.typeId;
    };
    ArrowTable.prototype.nanosToDate = function (nanos) {
        return new Date(nanos / 1e6);
    };
    return ArrowTable;
}());
export { ArrowTable };
