/*
 * Copyright (c) 2015 [[email protected] | [email protected]]
 *
 * 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.
 */

package com.youku.service.download;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

import android.annotation.SuppressLint;
import android.os.Environment;
import android.os.StatFs;

import com.baseproject.utils.UIUtils;
import com.youku.player.YoukuPlayerApplication;

/**
 * SDCardManager.SD卡管理,空间数据的获取
 * 
 * @author 刘仲男 [email protected]
 * @version v3.5
 * @created time 2012-11-5 下午1:16:02
 */
public class SDCardManager {

	private String sdPath;
	private long nSDTotalSize;
	private long nSDFreeSize;

	public SDCardManager(String sdPath) {
		this.sdPath = sdPath;
		init();
	}

	@SuppressWarnings("deprecation")
	private void init() {
		try {
			StatFs statFs = new StatFs(sdPath);
			long totalBlocks = statFs.getBlockCount();// 区域块数
			long availableBlocks = statFs.getAvailableBlocks();// 可利用区域块数
			long blockSize = statFs.getBlockSize();// 每个区域块大小
			nSDTotalSize = totalBlocks * blockSize;
			nSDFreeSize = availableBlocks * blockSize;
		} catch (Exception e) {

		}
	}

	/**
	 * 是否存在
	 * 
	 * @return
	 */
	public boolean exist() {
		return nSDTotalSize == 0 ? false : true;
	}

	/**
	 * 总空间
	 * 
	 * @return
	 */
	public long getTotalSize() {
		return nSDTotalSize;
	}

	/**
	 * 剩余空间
	 * 
	 * @return
	 */
	public long getFreeSize() {
		return nSDFreeSize;
	}

	/**
	 * 优酷视频占有空间大小(/youku/offlinedata/下的文件大小)
	 * 
	 * @return
	 */
	public long getYoukuVideoSpace() {
		try {
			if (sdPath.equals(getDefauleSDCardPath())) {
				// 固定加入p2p所占空间大小100M
//				if (AcceleraterServiceManager.isAccSupported(Youku.context)) {
//					return getYoukuOfflinedataSpace() + 100 * 1024 * 1024;
//				} else {
					return getYoukuOfflinedataSpace();
//				}
			} else {
				return getYoukuOfflinedataSpace();
			}
		} catch (Exception e) {
			return getYoukuOfflinedataSpace();
		}
	}

	private long getYoukuOfflinedataSpace() {
		File f = new File(sdPath + YoukuPlayerApplication.getDownloadPath());
		return f.exists() ? getFileSize(f) : 0;
	}

	private long getYoukudiskSpace() {
		File f = new File(sdPath + "/youku/youkudisk/");
		return f.exists() ? getFileSize(f) : 0;
	}

	/**
	 * 其他程序占有空间大小
	 * 
	 * @return
	 */
	public long getOtherSpace() {
		if (!exist())
			return 0;
		return nSDTotalSize - nSDFreeSize - getYoukuOfflinedataSpace()
				- getYoukudiskSpace();
	}

	/**
	 * 优酷视频所占空间比例n%
	 */
	public int getYoukuProgrss() {
		if (!exist())
			return 0;
		return (int) ((1000 * getYoukuVideoSpace()) / nSDTotalSize);
	}

	/**
	 * 其他程序所占空间比例n%
	 */
	public int getOtherProgrss() {
		if (!exist())
			return 0;
		return (int) ((1000 * getOtherSpace()) / nSDTotalSize);
	}

	/**
	 * TODO 递归取得文件夹大小
	 */
	private static long getFileSize(File f) {
		long size = 0;
		if (f.isDirectory()) {
			File files[] = f.listFiles();
			if (files != null) {
				for (int i = 0, n = files.length; i < n; i++) {
					if (files[i].isDirectory()) {
						size = size + getFileSize(files[i]);
					} else {
						size = size + files[i].length();
					}
				}
			}
		} else {
			size = f.length();
		}
		return size;
	}

	/** Returns 是否有SD卡 */
	public static boolean hasSDCard() {
		return Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}

	public static String getDefauleSDCardPath() {
		return hasSDCard() ? Environment.getExternalStorageDirectory()
				.getAbsolutePath() : "";
	}

	/**
	 * 获得外部存储路径
	 * 
	 * @return /mnt/sdcard或者/storage/extSdCard等多种名称
	 */
	@SuppressLint("NewApi")
	public static ArrayList<SDCardInfo> getExternalStorageDirectory() {
		ArrayList<SDCardInfo> list = new ArrayList<SDCardInfo>();
		if (UIUtils.hasKitKat()) {
			// OS 4.4 以上读取外置 SD 卡
			final File[] externalFiles = YoukuPlayerApplication.context
					.getExternalFilesDirs(null);
			if (null != externalFiles) {
				SDCardInfo info = new SDCardInfo();
				info.path = getDefauleSDCardPath();
				info.isExternal = false;
				list.add(info);
				if (externalFiles.length > 1 && (null != externalFiles[1])) {
					SDCardInfo externalInfo = new SDCardInfo();
					externalInfo.path = externalFiles[1].getAbsolutePath();
					externalInfo.isExternal = true;
					list.add(externalInfo);
				}
			}
			return list;
		} else {
			Runtime runtime = Runtime.getRuntime();
			Process proc;
			try {
				proc = runtime.exec("mount");
				// InputStream is = Youku.context.getAssets().open("mount.txt");
				InputStream is = proc.getInputStream();
				InputStreamReader isr = new InputStreamReader(is);
				String line;
				// String mount = new String();
				BufferedReader br = new BufferedReader(isr);
				String defauleSDCardPath = getDefauleSDCardPath();
				//用于盛放已经判断过的路径,省时高效
				HashMap<String,Integer> tempPath = new HashMap<String,Integer>();
				while ((line = br.readLine()) != null) {
//					 Logger.d("nathan2", line);
					// "fat"为不可卸载的;"fuse"为可卸载的;但是有的手机不适用,所以统一去处理;storage为一些三星手机的存储路径标识
					if (line.contains("fat") || line.contains("fuse")
							|| line.contains("storage")) {
						if (line.contains("secure") || line.contains("asec")
								|| line.contains("firmware")
								|| line.contains("shell")
								|| line.contains("obb")
								|| line.contains("legacy")
								|| line.contains("data")
								|| line.contains("tmpfs")) {

							continue;
						}
						String columns[] = line.split(" ");
						for (int i = 0; i < columns.length; i++) {
							String path = columns[i];
							//一加手机的"/dev/fuse"是假地址
							if (path.contains("/") && !path.contains("data") && !path.contains("Data")
									&& !path.contains("/dev/fuse")) {
								try {
									if (tempPath.containsKey(path)) {
										continue;
									} else {
										tempPath.put(path, 0);
										SDCardManager m = new SDCardManager(path);
										if (m.getTotalSize() >= 1024 * 1024 * 1024) {
											SDCardInfo info = new SDCardInfo();
											info.path = columns[i];
											if (info.path.equals(defauleSDCardPath)) {
												info.isExternal = false;
											} else {
												info.isExternal = true;
											}
											list.add(info);
										}
									}
								} catch (Exception e) {
									continue;
								}
							}
						}
					}
				}
				tempPath.clear();
				if (list.size() == 1) {
					if (!defauleSDCardPath.equals(list.get(0).path)) {
						SDCardInfo info = new SDCardInfo();
						info.path = defauleSDCardPath;
						info.isExternal = false;
						list.add(info);
					} else {
						YoukuPlayerApplication.savePreference("download_file_path",
								defauleSDCardPath);
					}
				} else if (list.size() == 0) {
					if (defauleSDCardPath != null
							&& defauleSDCardPath.length() != 0) {
						SDCardInfo info = new SDCardInfo();
						info.path = defauleSDCardPath;
						info.isExternal = false;
						list.add(info);
					}
				}
				if (list.size() > 1) {
					Set<SDCardInfo> s = new TreeSet<SDCardInfo>(
							new Comparator<SDCardInfo>() {

								@Override
								public int compare(SDCardInfo o1, SDCardInfo o2) {
									return o1.path.compareTo(o2.path);
								}

							});
					s.addAll(list);
					list = new ArrayList<SDCardInfo>(s);
				}
				return list;
			} catch (IOException e) {

			}
			return null;

		}
	}

	public static class SDCardInfo {

		/** 路径/mnt/sdcard或者/storage/extSdCard等多种名称 */
		public String path;

		/** 是否是外部存储 */
		public boolean isExternal;
	}
}