package com.secspace.lib.common.utils;


import android.graphics.BitmapFactory;
import android.util.ArrayMap;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class FileTypeUtil {
    private static final String TAG = "FileTypeUtil";

    private static ArrayMap<String, String> FILE_TYPE_MAP = new ArrayMap<>();
    private static ArrayMap<String, String> IMAGE_TYPE_MAP = new ArrayMap<>();
    private static ArrayMap<String, String> VIDEO_TYPE_MAP = new ArrayMap<>();
    private static ArrayMap<String, String> AUDIO_TYPE_MAP = new ArrayMap<>();
    private static ArrayMap<String, String> DOC_TYPE_MAP = new ArrayMap<>();

    static {
        getAllFileType();
        getImageFileType();
        getVideoFileType();
        getAudioFileType();
        getDocFileType();
    }

    private static void getAllFileType() {
        FILE_TYPE_MAP.put("ffd8ff", "jpg"); //JPEG (jpg)
        FILE_TYPE_MAP.put("89504e", "png"); //PNG (png)
        FILE_TYPE_MAP.put("474946", "gif"); //GIF (gif)
        FILE_TYPE_MAP.put("49492a", "tif"); //TIFF (tif)
        FILE_TYPE_MAP.put("424d22", "bmp"); //16色位图(bmp)
        FILE_TYPE_MAP.put("424d82", "bmp"); //24位位图(bmp)
        FILE_TYPE_MAP.put("424d8e", "bmp"); //256色位图(bmp)
        FILE_TYPE_MAP.put("414331", "dwg"); //CAD (dwg)
        FILE_TYPE_MAP.put("3c2144", "html"); //HTML (html)
        FILE_TYPE_MAP.put("3c2164", "htm"); //HTM (htm)
        FILE_TYPE_MAP.put("48544d", "css"); //css
        FILE_TYPE_MAP.put("696b2e", "js"); //js
        FILE_TYPE_MAP.put("7b5c72", "rtf"); //Rich Text Format (rtf)
        FILE_TYPE_MAP.put("384250", "psd"); //Photoshop (psd)
        FILE_TYPE_MAP.put("46726f", "eml"); //Email [Outlook Express 6] (eml)
        FILE_TYPE_MAP.put("d0cf11", "doc"); //MS Excel 注意：word、msi 和 excel的文件头一样
        FILE_TYPE_MAP.put("d0cf11", "vsd"); //Visio 绘图
        FILE_TYPE_MAP.put("537461", "mdb"); //MS Access (mdb)
        FILE_TYPE_MAP.put("252150", "ps");
        FILE_TYPE_MAP.put("255044", "pdf"); //Adobe Acrobat (pdf)
        FILE_TYPE_MAP.put("2e524d", "rmvb"); //rmvb/rm相同
        FILE_TYPE_MAP.put("464c56", "flv"); //flv与f4v相同
        FILE_TYPE_MAP.put("000000", "mp4");
        FILE_TYPE_MAP.put("494433", "mp3");
        FILE_TYPE_MAP.put("000001", "mpg"); //
        FILE_TYPE_MAP.put("3026b2", "wmv"); //wmv与asf相同
        FILE_TYPE_MAP.put("524946", "wav"); //Wave (wav)
        FILE_TYPE_MAP.put("524946", "avi");
        FILE_TYPE_MAP.put("4d5468", "mid"); //MIDI (mid)
        FILE_TYPE_MAP.put("504b03", "zip");
        FILE_TYPE_MAP.put("526172", "rar");
        FILE_TYPE_MAP.put("235468", "ini");
        FILE_TYPE_MAP.put("504b03", "jar");
        FILE_TYPE_MAP.put("4d5a90", "exe");//可执行文件
        FILE_TYPE_MAP.put("3c2540", "jsp");//jsp文件
        FILE_TYPE_MAP.put("4d616e", "mf");//MF文件
        FILE_TYPE_MAP.put("3c3f78", "xml");//xml文件
        FILE_TYPE_MAP.put("494e53", "sql");//xml文件
        FILE_TYPE_MAP.put("706163", "java");//java文件
        FILE_TYPE_MAP.put("406563", "bat");//bat文件
        FILE_TYPE_MAP.put("1f8b08", "gz");//gz文件
        FILE_TYPE_MAP.put("6c6f67", "properties");//bat文件
        FILE_TYPE_MAP.put("cafeba", "class");//bat文件
        FILE_TYPE_MAP.put("495453", "chm");//bat文件
        FILE_TYPE_MAP.put("040000", "mxp");//bat文件
        FILE_TYPE_MAP.put("504b03", "docx");//docx文件
        FILE_TYPE_MAP.put("d0cf11", "wps");//WPS文字wps、表格et、演示dps都是一样的
        FILE_TYPE_MAP.put("643130", "torrent");
        FILE_TYPE_MAP.put("6D6F6F", "mov"); //Quicktime (mov)
        FILE_TYPE_MAP.put("FF5750", "wpd"); //WordPerfect (wpd)
        FILE_TYPE_MAP.put("CFAD12", "dbx"); //Outlook Express (dbx)
        FILE_TYPE_MAP.put("214244", "pst"); //Outlook (pst)
        FILE_TYPE_MAP.put("AC9EBD", "qdf"); //Quicken (qdf)
        FILE_TYPE_MAP.put("E38285", "pwl"); //Windows Password (pwl)
        FILE_TYPE_MAP.put("2E7261", "ram"); //Real Audio (ram)
    }

    private static void getImageFileType() {
        IMAGE_TYPE_MAP.put("ffd8ff", "jpg"); //JPEG (jpg)
        IMAGE_TYPE_MAP.put("89504e", "png"); //PNG (png)
        IMAGE_TYPE_MAP.put("474946", "gif"); //GIF (gif)
        IMAGE_TYPE_MAP.put("49492a", "tif"); //TIFF (tif)
        IMAGE_TYPE_MAP.put("424d22", "bmp"); //16色位图(bmp)
        IMAGE_TYPE_MAP.put("424d82", "bmp"); //24位位图(bmp)
        IMAGE_TYPE_MAP.put("424d8e", "bmp"); //256色位图(bmp)
    }

    private static void getVideoFileType() {
        VIDEO_TYPE_MAP.put("2e524d", "rmvb"); //rmvb/rm相同
        VIDEO_TYPE_MAP.put("464c56", "flv"); //flv与f4v相同
        VIDEO_TYPE_MAP.put("000000", "mp4");
        VIDEO_TYPE_MAP.put("000001", "mpg"); //
        VIDEO_TYPE_MAP.put("524946", "avi");
        VIDEO_TYPE_MAP.put("6D6F6F", "mov"); //Quicktime (mov)
    }

    private static void getAudioFileType() {
        AUDIO_TYPE_MAP.put("494433", "mp3");
        AUDIO_TYPE_MAP.put("3026b2", "wmv"); //wmv与asf相同
        AUDIO_TYPE_MAP.put("524946", "wav"); //Wave (wav)
        AUDIO_TYPE_MAP.put("2E7261", "ram"); //Real Audio (ram)
    }

    private static void getDocFileType() {
        DOC_TYPE_MAP.put("d0cf11", "doc"); //MS Excel 注意：word、msi 和 excel的文件头一样
        DOC_TYPE_MAP.put("255044", "pdf"); //Adobe Acrobat (pdf)
        DOC_TYPE_MAP.put("504b03", "docx");//docx文件
        DOC_TYPE_MAP.put("d0cf11", "wps");//WPS文字wps、表格et、演示dps都是一样的
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static String getFileType(String filePath) {
        String res = null;
        try {
            FileInputStream is = new FileInputStream(filePath);
            byte[] b = new byte[3];
            is.read(b, 0, b.length);
            String fileCode = bytesToHexString(b);
            Log.d(TAG, "fileCode: " + fileCode + "   " + FILE_TYPE_MAP.size());
            return FILE_TYPE_MAP.get(fileCode);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 是否是图片
     *
     * @return
     */
    public static boolean isImageFile(File file) {
        return IMAGE_TYPE_MAP.containsValue(getFileType(file.getAbsolutePath()));
    }

    public static boolean isImageFile(String fileType) {
        return IMAGE_TYPE_MAP.containsValue(fileType);
    }

    public static boolean isImageFile2(String filePath) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        Log.d(TAG, "isImageFile options.outWidth: " + options.outWidth);
        if (options.outWidth == -1) {
            return false;
        }
        return true;
    }

    /**
     * 是否是视频
     *
     * @return
     */
    public static boolean isVideoFile(File file) {
        return VIDEO_TYPE_MAP.containsValue(getFileType(file.getAbsolutePath()));
    }

    public static boolean isVideoFile(String fileType) {
        return VIDEO_TYPE_MAP.containsValue(fileType);
    }

    /**
     * 是否是音频
     *
     * @return
     */
    public static boolean isAudioFile(File file) {
        return AUDIO_TYPE_MAP.containsValue(getFileType(file.getAbsolutePath()));
    }

    public static boolean isAudioFile(String fileType) {
        return AUDIO_TYPE_MAP.containsValue(fileType);
    }

    /**
     * 是否是文档
     *
     * @return
     */
    public static boolean isDocFile(File file) {
        return DOC_TYPE_MAP.containsValue(file.getAbsolutePath());
    }

    public static boolean isDocFile(String fileType) {
        return DOC_TYPE_MAP.containsValue(fileType);
    }


    public static boolean isGifFile(String path) {
        try {
            FileInputStream inputStream = new FileInputStream(path);
            int[] flags = new int[5];
            flags[0] = inputStream.read();
            flags[1] = inputStream.read();
            flags[2] = inputStream.read();
            flags[3] = inputStream.read();
            inputStream.skip(inputStream.available() - 1);
            flags[4] = inputStream.read();
            inputStream.close();
            return flags[0] == 71 && flags[1] == 73 && flags[2] == 70 && flags[3] == 56 && flags[4] == 0x3B;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}
