<template>
    <div>
        <div v-if="loading">
            <div class="spinner spinner-xl blue"></div>
        </div>
        <div class="filemanager" v-else>
            <div class="header">
                <div class="flex-none w-8"></div>
                <div class="flex-1">Name</div>
                <div class="flex-1 text-right">Size</div>
                <div class="flex-1 text-right">Modified</div>
                <div class="flex-none w-1/6">Actions</div>
            </div>
            <div class="row" v-for="folder in folders">
                <div class="flex-none icon"><folder-icon/></div>
                <div class="flex-1">{{folder.name}}</div>
                <div class="flex-1 text-right text-grey-dark"></div>
                <div class="flex-1 text-right text-grey-dark">{{formatDate(folder.modified)}}</div>
                <div class="flex-none w-1/6"></div>
            </div>
            <div class="row" v-for="file in files">
                <div class="flex-none icon">
                    <file-text-icon v-if="!file.symlink"/>
                    <link2-icon v-else/>
                </div>
                <div class="flex-1">{{file.name}}</div>
                <div class="flex-1 text-right text-grey-dark">{{readableSize(file.size)}}</div>
                <div class="flex-1 text-right text-grey-dark">{{formatDate(file.modified)}}</div>
                <div class="flex-none w-1/6"></div>
            </div>
        </div>
    </div>
</template>

<script>
    import filter from 'lodash/filter';
    import format from 'date-fns/format';
    import { mapState } from 'vuex';
    import { FileTextIcon, FolderIcon, Link2Icon } from 'vue-feather-icons';

    export default {
        name: 'file-manager-page',
        components: { FileTextIcon, FolderIcon, Link2Icon },

        computed: {
            ...mapState('server', ['server', 'credentials']),
        },

        data: function () {
            return {
                directory: '/',
                loading: true,

                files: [],
                folders: [],
            };
        },

        mounted: function () {
            this.listDirectory();
        },

        methods: {
            /**
             * List the contents of a directory.
             */
            listDirectory: function () {
                window.axios.get(`${this.credentials.node}/v1/server/directory/${this.directory}`, {
                    headers: {
                        'X-Access-Server': this.server.uuid,
                        'X-Access-Token': this.credentials.key,
                    }
                })
                    .then((response) => {
                        this.files = filter(response.data, function (o) {
                            return o.file;
                        });

                        this.folders = filter(response.data, function (o) {
                            return o.directory;
                        });
                    })
                    .catch(console.error)
                    .finally(() => {
                        this.loading = false;
                    });
            },

            /**
             * Return the human readable filesize for a given number of bytes. This
             * uses 1024 as the base, so the response is denoted accordingly.
             *
             * @param {Number} bytes
             * @return {String}
             */
            readableSize: function (bytes) {
                if (Math.abs(bytes) < 1024) {
                    return `${bytes} Bytes`;
                }

                let u = -1;
                const units = ['KiB', 'MiB', 'GiB', 'TiB'];

                do {
                    bytes /= 1024;
                    u++;
                } while (Math.abs(bytes) >= 1024 && u < units.length - 1);

                return `${bytes.toFixed(1)} ${units[u]}`
            },

            /**
             * Format the given date as a human readable string.
             *
             * @param {String} date
             * @return {String}
             */
            formatDate: function (date) {
                return format(date, 'MMM D, YYYY [at] HH:MM');
            },
        }
    };
</script>