'''
Author: your name
Date: 2021-06-21 14:52:24
LastEditTime: 2021-06-29 16:33:06
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \evm-store\tools\modules\file-manager\main.py
'''

import os
import shutil
import pprint
from pathlib import Path, PurePosixPath, PureWindowsPath
import platform
import json
from fs.osfs import OSFS
from fs import open_fs
from fs.walk import Walker

disk_root = "D:\\projects\\scriptiot\\evm_app_store_files"

class FileManager(object):
    def __init__(self) -> None:
        pass

    '''
    @description: 根据前端传递的路径参数，获取该路径的目录以及文件信息，文件类别，可以看做是一个盘符
    @param {*} self
    @return {*}
    '''
    def initialize(self):
        '''
        disks: {
            files: {driver: "local"},
            images: {driver: "local"}
        }
        lang: "en"
        leftDisk: null
        rightDisk: null
        windowsConfig: 2
        '''

        result = {
            "disks": {},
            "lang": "zh",
            "leftDisk": None,
            "rightDisk": None,
            "windowsConfig": 1
        }

        # 这里需要过滤，有些目录只能管理员才能查看
        for d in os.listdir(disk_root):
            if os.path.isdir(os.sep.join([disk_root, d])):
                result["disks"].update({
                    d: { "driver": "local" }
                })

        return result

    '''
    @description: 获取当前类别的目录信息
    @param {*} self
    @return {*}
    '''
    def content(self, disk, target_path='/'):
        '''
        目录信息结构体：
        {
            basename: "docs"
            dirname: ""
            path: "docs"
            timestamp: 1556821372
            type: "dir"
        },
        {
            basename: "cars"
            dirname: "wallpapers"
            path: "wallpapers/cars"
            timestamp: 1544277291
            type: "dir"
        }

        文件信息结构体：
        {
            basename: "alfa.sql"
            dirname: "code"
            extension: "sql"
            filename: "alfa"
            path: "code/alfa.sql"
            size: 3208
            timestamp: 1544277274
            type: "file"
        }
        '''

        sys_str = platform.system()
        # disk = "uploads" # disk就是文件根目录，只能以某个目录为根目录，浏览这个目录下面的所有文件
        # target_path = None # 就是以disk为根目录的路径，判断是否以**/**或者**\\**开头
        if not target_path.startswith("/"):
            target_path = "/" + target_path
        
        result = {
            "directories": [],
            "files": []
        }

        disk_path = os.sep.join([disk_root, disk])
        if not os.path.exists(disk_path):
            return result
        if not os.path.exists(os.path.normpath(os.sep.join([disk_path, target_path]))):
            return result

        os.chdir(disk_path)
        home_fs = open_fs('.')

        for file in home_fs.scandir(target_path, namespaces=['details']):
            if file.is_dir:
                tmp = {
                    "basename": file.name,
                    "dirname": os.path.basename(target_path),
                    "path": os.path.normpath(os.sep.join([target_path, file.name])),
                    "timestamp": int(file.raw.get("details").get("modified")),
                    "type": "dir"
                }
                if (sys_str == "Windows"):
                    p = PureWindowsPath(tmp.get("path"))
                    tmp["path"] = str(p.relative_to("\\"))
                else:
                    p = PurePosixPath(tmp.get("path"))
                    tmp["path"] = str(p.relative_to('/'))
                result["directories"].append(tmp)
            else:
                fn, ex = os.path.splitext(file.name)
                tmp = {
                    "basename": file.name,
                    "dirname": os.path.basename(target_path),
                    "extension": ex[1:],
                    "filename": fn,
                    "path": os.path.normpath(os.sep.join([target_path, file.name])),
                    "size": file.size,
                    "timestamp": int(file.raw.get("details").get("modified")),
                    "type": "file"
                }
                if (sys_str == "Windows"):
                    p = PureWindowsPath(tmp.get("path"))
                    tmp["path"] = str(p.relative_to("\\"))
                else:
                    p = PurePosixPath(tmp.get("path"))
                    tmp["path"] = str(p.relative_to('/'))
                result["files"].append(tmp)

        home_fs.close()
        with open("result.json", "w") as f:
            json.dump(result, f)
            f.write(json.dumps(result, ensure_ascii=True))

        pprint.pprint(result)
        return result

    '''
    @description: 获取目录结构树
    @param {*} self
    @return {*}
    '''
    def tree(self, disk, target_path="/"):
        '''
        {
            basename: "trees"
            dirname: "wallpapers/nature"
            path: "wallpapers/nature/trees"
            props: {
                hasSubdirectories: false
            }
            timestamp: 1544277291
            type: "dir"
        }
        '''

        if not target_path.startswith("/"):
            target_path = "/" + target_path

        result = []

        disk_path = os.sep.join([disk_root, disk])
        if not os.path.exists(disk_path):
            return result
        if not os.path.exists(os.path.normpath(os.sep.join([disk_path, target_path]))):
            return result

        os.chdir(disk_path)
        home_fs = OSFS(os.getcwd())

        rp = Path(disk_root)
        print("%%%%", rp)
        p = Path(disk_path)
        for child in p.iterdir():
            print("//////////", child.is_dir(), child.resolve(), child.name, child.parent, child.root, child.drive, child.relative_to(rp))
        print("------------------->", p)

        # 获取当前目录下所有目录、文件、子目录以及子文件的信息。递归获取
        for step in home_fs.walk():
            result.append({
                "basename": os.path.basename(step.path),
                "dirname": os.path.dirname(step.path),
                "path": step.path,
                "props": {
                    "hasSubdirectories": True if len(step.files) else False
                },
                # "timestamp": int(os.path.getatime(os.sep.join([target_path, step.path]))),
                "type": "dir"
            })

        home_fs.close()

        pprint.pprint(result)

        return result

fileManager = FileManager()

if __name__ == "__main__":
    '''
    python -m memory_profiler example.py
    '''
    # from memory_profiler import profile
    # @profile
    # def test():
    #     pass

    # result = fileManager.initialize()
    # print(result)
    
    # result = fileManager.content("uploads", "evueapps/evm")
    # print(result)

    result = fileManager.tree("uploads", "evueapps/evm")
    print(result)