import * as extName from 'ext-name';
export interface DriveFileParam {
  name: string;
  size: number;
  mtime: number;
  imgb?: number;
}
export class DriveFile {
  public name: string;
  public fullName: string;
  public size: number;
  public mtime: number;
  public createdAt: Date;
  public ext: string;
  public mime: string;
  public icon: string; // material-design font
  public rawData: DriveFileParam | File;
  public thumbnail: Blob;
  public imgb: number; // Directory listing entries will have an imgb key if they have a thumbnail.

  public static FILE_TYPES_ICONS = {
    'file-document': ['txt'],
    'file-pdf': ['pdf'],
    'language-css3': ['css', 'scss', 'sass'],
    'language-typescript': ['ts'],
    'language-javascript': ['js'],
    'language-python': ['py'],
    'language-html5': ['html'],
    'language-cpp': ['cpp'],
    'language-c': ['c'],
    'language-csharp': ['cs'],
    'language-java': ['java'],
    'language-php': ['php'],
    'language-ruby': ['ruby'],
    'file-code': [
      'json',
      'c',
      'cgi',
      'pl',
      'class',
      'cpp',
      'cs',
      'h',
      'java',
      'php',
      'py',
      'sh',
      'swift',
      'vb',
    ],
    'music-box': ['aif', 'cda', 'mid', 'midi', 'mp3', 'mpa', 'ogg', 'wav', 'wma', 'wpl'],
    'folder-zip': ['7z', 'arj', 'deb', 'pkg', 'rar', 'rpm', 'gz', 'z', 'zip'],
    disc: ['bin', 'dmg', 'iso', 'toast', 'vcd'],
    database: ['csv', 'dat', 'db', 'dbf', 'log', 'mdb', 'sav', 'sql', 'tar', 'xml'],
    email: ['email', 'eml', 'emlx', 'msg', 'oft', 'ost', 'pst', 'vcf'],
    application: [
      'apk',
      'bat',
      'bin',
      'cgi',
      'pl',
      'com',
      'exe',
      'gadget',
      'jar',
      'msi',
      'py',
      'wsf',
    ],
    'format-size': ['fnt', 'fon', 'otf', 'ttf'],
    image: ['ai', 'bmp', 'gif', 'ico', 'jpeg', 'jpg', 'png', 'ps', 'psd', 'svg', 'tif', 'tiff'],
    'web-box': [
      'asp',
      'aspx',
      'cer',
      'cfm',
      'cgi',
      'pl',
      'css',
      'html',
      'htm',
      'js',
      'jsp',
      'part',
      'php',
      'py',
      'rss',
      'xhtml',
    ],
    'file-powerpoint': ['key', 'odp', 'pps', 'ppt', 'pptx'],
    'file-excel': ['ods', 'xls', 'xlsm', 'xlsx'],
    'file-cog': [
      'conf',
      'bak',
      'cab',
      'cfg',
      'cpl',
      'cur',
      'dll',
      'dmp',
      'drv',
      'icns',
      'ico',
      'ini',
      'ink',
      'msi',
      'sys',
      'tmp',
    ],
    'video-box': [
      '3g2',
      '3gp',
      'avi',
      'flv',
      'h264',
      'm4v',
      'mkv',
      'mov',
      'mp4',
      'mpg',
      'mpeg',
      'rm',
      'swf',
      'vob',
      'wmv',
    ],
    'file-word': ['doc', 'docx', 'odt', 'pdf', 'rtf', 'tex', 'txt', 'wpd'],
  };

  constructor(data: DriveFileParam | File) {
    this.rawData = data;
    this.name = data['name'];
    this.fullName = data['name'];
    this.size = data['size']; // undefined is it is a dir
    this.mtime = data['mtime'] || data['lastModified'];
    this.createdAt = new Date(data['mtime'] * 1000);
    this.imgb = data['imgb'];

    if (this.isDir()) {
      this.ext = 'dir';
    } else {
      this.updateName(this.name);
    }

    this.icon = this.calcIconFromExt(this.ext.toLocaleLowerCase());
  }

  public updateName = (name: string) => {
    this.fullName = name;
    let slice = name.split('.');
    if (slice.length > 1) {
      this.ext = slice[slice.length - 1];
      this.name = slice.slice(0, slice.length - 1).join('.');
    } else {
      this.ext = '';
    }

    let extResult = extName(this.fullName.toLowerCase());
    if (extResult.length > 0 && extResult[0].mime) {
      this.mime = extResult[0].mime;
    } else {
      this.mime = 'application/octet-stream'; // default is binary
    }
  };

  public isDir() {
    return this.size === undefined;
  }

  public shallowEquals(other: DriveFile): boolean {
    return this.fullName == other.fullName && this.size == other.size;
  }

  private calcIconFromExt(ext) {
    // https://materialdesignicons.com/ - look for icons's string here
    if (ext == 'dir') return 'folder';
    if (ext == '') return 'file';

    for (let key in DriveFile.FILE_TYPES_ICONS) {
      if (DriveFile.FILE_TYPES_ICONS[key].includes(ext)) return key;
    }

    return 'file';
  }
}
