/*
 * Copyright (C) 2013 Fairphone Project
 *
 * 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.fairphone.updater.tools;

import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.fairphone.updater.BetaEnabler;
import com.fairphone.updater.R;
import com.fairphone.updater.UpdaterService;
import com.fairphone.updater.data.DownloadableItem;
import com.fairphone.updater.data.Store;
import com.fairphone.updater.data.UpdaterData;
import com.fairphone.updater.data.Version;
import com.fairphone.updater.data.VersionParserHelper;
import com.stericson.RootTools.RootTools;
import com.stericson.RootTools.exceptions.RootDeniedException;
import com.stericson.RootTools.execution.CommandCapture;
import com.stericson.RootTools.execution.Shell;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.concurrent.TimeoutException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils
{
    private static final String TAG = Utils.class.getSimpleName();
    private static final int DELAY_100_MILLIS = 100;
    public static final int DELAY_HALF_SECOND = 500;
    public static final long SECONDS_IN_MINUTE = 60L;
    public static final long MINUTES_IN_HOUR = 60L;

    private static final double BUFFER_1024_BYTES = 1024d;
    // --Commented out by Inspection (06/02/2015 12:27):public static final int BUFFER_SIZE_4_KBYTES = 4096;
    public static final int BUFFER_SIZE_2_KBYTES = 2048;
    private static final int BUFFER_SIZE_8_KBYTES = 8192;
    public static final int BUFFER_SIZE_10_MBYTES = 10240;
    private static final int RADIX_BASE_16 = 16;
    private static final double PERCENT_100 = 100d;
    private static final char CHAR_SPACE = ' ';
    private static final char CHAR_ZERO = '0';
    public static final int GAPPS_STORE_NUMBER = 0;

    private static double getPartitionSizeInGBytes(File path)
    {
        double availableBlocks = getPartitionSizeInBytes(path);
        double sizeInGB = ((availableBlocks / BUFFER_1024_BYTES) / BUFFER_1024_BYTES) / BUFFER_1024_BYTES;
        Log.d(TAG, path.getPath() + " size(GB): " + sizeInGB);
        return sizeInGB;
    }

// --Commented out by Inspection START (06/02/2015 12:26):
//    public static double getPartitionSizeInMBytes(File path)
//    {
//        double availableBlocks = getPartitionSizeInBytes(path);
//        double sizeInMB = ((availableBlocks / BUFFER_1024_BYTES)) / BUFFER_1024_BYTES;
//        return sizeInMB;
//    }
// --Commented out by Inspection STOP (06/02/2015 12:26)

    private static long getPartitionSizeInBytes(File path)
    {
        android.os.StatFs stat = new android.os.StatFs(path.getPath());
	    long blockSize, blockCount;
	    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
		    blockSize = stat.getBlockSizeLong();
		    blockCount = stat.getBlockCountLong();
	    } else {
		    // deprectation warnings disabled due to the need to support SDK 17 (FP1)
		    //noinspection deprecation
		    blockSize = stat.getBlockSize();
		    //noinspection deprecation
		    blockCount = stat.getBlockCount();
	    }
	    return blockCount * blockSize;
    }

    public static long getAvailablePartitionSizeInBytes(File path)
    {
        android.os.StatFs stat = new android.os.StatFs(path.getPath());

	    long blockSize, blockCount;
	    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
		    blockSize = stat.getBlockSizeLong();
		    blockCount = stat.getAvailableBlocksLong();
	    } else {
		    // deprectation warnings disabled due to the need to support SDK 17 (FP1)
		    //noinspection deprecation
		    blockSize = stat.getBlockSize();
		    //noinspection deprecation
		    blockCount = stat.getAvailableBlocks();
	    }
	    return blockCount * blockSize;
    }

    public static void startUpdaterService(Context context, boolean forceDownload)
    {
        Intent i = new Intent(context, UpdaterService.class);
        i.putExtra(UpdaterService.EXTRA_FORCE_CONFIG_FILE_DOWNLOAD, forceDownload);
        context.startService(i);
    }

// --Commented out by Inspection START (06/02/2015 12:26):
//    public static void stopUpdaterService(Context context)
//    {
//        boolean isRunning = isServiceRunning(context);
//
//        if (isRunning)
//        {
//            Log.i(TAG, "Stoping Updater Service...");
//            Intent i = new Intent(context, UpdaterService.class);
//            context.stopService(i);
//            try
//            {
//                Thread.sleep(DELAY_100_MILLIS * 2);
//            } catch (InterruptedException e)
//            {
//                Log.w(TAG, "Stop Updater service delay error: " + e.getLocalizedMessage());
//            }
//        }
//    }
// --Commented out by Inspection STOP (06/02/2015 12:26)

    // **************************************************************************************************************
    // HELPERS
    // **************************************************************************************************************

    public static boolean checkMD5(String md5, File updateFile)
    {

        if (updateFile == null || !updateFile.exists())
        {
            return false;
        }

        if (md5 == null || md5.isEmpty())
        {
            Log.e(TAG, "MD5 String NULL or UpdateFile NULL");
            return false;
        }

        String calculatedDigest = calculateMD5(updateFile);
        if (calculatedDigest == null)
        {
            Log.e(TAG, "calculatedDigest NULL");
            return false;
        }

        return calculatedDigest.equalsIgnoreCase(md5);
    }

    public static String calculateMD5(File updateFile)
    {
        MessageDigest digest;
        try
        {
            digest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e)
        {
            Log.e(TAG, "Exception while getting Digest", e);
            return null;
        }

        InputStream is;
        try
        {
            is = new FileInputStream(updateFile);
        } catch (FileNotFoundException e)
        {
            Log.e(TAG, "Exception while getting FileInputStream", e);
            return null;
        }

        byte[] buffer = new byte[BUFFER_SIZE_8_KBYTES];
        int read;
        try
        {
            while ((read = is.read(buffer)) > 0)
            {
                digest.update(buffer, 0, read);
            }
            byte[] md5sum = digest.digest();
            BigInteger bigInt = new BigInteger(1, md5sum);
            String output = bigInt.toString(RADIX_BASE_16);
            // Fill to 32 chars
            output = String.format("%32s", output).replace(CHAR_SPACE, CHAR_ZERO);
            return output;
        } catch (IOException e)
        {
            Log.e(TAG, "Error digesting MD5: " + e.getLocalizedMessage());
            return null;
//            throw new RuntimeException("Unable to process file for MD5", e);
        } finally
        {
            try
            {
                is.close();
            } catch (IOException e)
            {
                Log.e(TAG, "Exception on closing MD5 input stream", e);
            }
        }
    }

    public static String getModelAndOS(Context context)
    {
        StringBuilder sb = new StringBuilder();

        // attach the model and the os
        sb.append("?");
        sb.append("model=").append(Build.MODEL.replaceAll("\\s", ""));
        Version currentVersion = VersionParserHelper.getDeviceVersion(context);

        if (currentVersion != null)
        {
            sb.append("&");
            sb.append("os=").append(currentVersion.getAndroidVersion());
        }

        return sb.toString();
    }

	public static void copy(File src, File dst) throws IOException {
		if (PrivilegeChecker.isPrivilegedApp()) {
			copyPrivileged(src, dst);
		} else {
			copyUnprivileged(src, dst);
		}
	}

	private static void copyUnprivileged(File src, File dst) throws IOException {
		if (RootTools.isAccessGiven()) {
			RootTools.copyFile(src.getPath(), dst.getPath(), false, false);
		} else {
			throw new IOException("No root permissions granted.");
		}
	}

	private static void copyPrivileged(File src, File dst) throws IOException {
		FileInputStream inStream = new FileInputStream(src);
		FileOutputStream outStream = new FileOutputStream(dst);
		FileChannel inChannel = inStream.getChannel();
		FileChannel outChannel = outStream.getChannel();
		inChannel.transferTo(0, inChannel.size(), outChannel);
		inStream.close();
		outStream.close();
    }

    public static void clearCache()
    {
        if(PrivilegeChecker.isPrivilegedApp()) {
            File f = Environment.getDownloadCacheDirectory();
            File[] files = f.listFiles();
            if (files != null) {
                Log.d(TAG, "Size: " + files.length);
                for (File file : files) {
                    String filename = file.getName();

                    if (filename.endsWith(".zip")) {
                        final boolean delete = file.delete();
                        if (delete) {
                            Log.d(TAG, "Deleted file " + filename);
                        } else {
                            Log.d(TAG, "Failed to delete file " + filename);
                        }
                    }
                }
            }
        } else {
            if(RootTools.isAccessGiven()) {
                try {
                    Shell.runRootCommand(new CommandCapture(0, "rm -f *.zip"));
                } catch (IOException | TimeoutException |RootDeniedException e) {
                    Log.w(TAG, "Failed to clear cache: " + e.getLocalizedMessage());
                }
            }
        }
    }

    public static boolean hasUnifiedPartition(Resources resources)
    {
        File path = Environment.getDataDirectory();
        double sizeInGB = Utils.getPartitionSizeInGBytes(path);
        double roundedSize = Math.ceil(sizeInGB * PERCENT_100) / PERCENT_100;
        Log.d(TAG, "/data size: " + roundedSize + "Gb");

        double fp1DataPartitionSize = (double) resources.getInteger(R.integer.FP1DataPartitionSizeMb) / BUFFER_1024_BYTES;
        // Add a little buffer to the 1gb default just in case
        return roundedSize > fp1DataPartitionSize;
    }

    public static String getPartitionDownloadPath(Resources resources)
    {
        String downloadPath = "";
        if (Build.MODEL.equals(resources.getString(R.string.FP1Model)))
        {
            downloadPath =
                    Utils.hasUnifiedPartition(resources) ? resources.getString(R.string.unifiedDataPartition) : resources
                            .getString(R.string.oneGBDataPartition);
        }
        return downloadPath;
    }

    public static boolean canCopyToCache(File file)
    {
        double fileSize = file.length();
        double cacheSize = Utils.getPartitionSizeInBytes(Environment.getDownloadCacheDirectory());
        return fileSize > 0 && cacheSize >= fileSize;
    }

    public static String getFilenameFromDownloadableItem(DownloadableItem item, boolean isVersion)
    {
        StringBuilder filename;

        if(isVersion)
        {
            filename = getFilenameForItem(item, "update_");
        }
        else
        {
            filename = getFilenameForItem(item, "store_");
        }

        return filename.toString();
    }

    private static StringBuilder getFilenameForItem(DownloadableItem item, String type) {
        StringBuilder filename = new StringBuilder();
        filename.append("fp_");
        if (item != null)
        {
            filename.append(type);
            filename.append(item.getNumber());
        }
        filename.append(".zip");
        return filename;
    }
    
    public static String getDownloadTitleFromDownloadableItem(Resources resources, DownloadableItem item, boolean isVersion){
        String title = "";
        if (item != null)
        {
            if (isVersion)
            {
                Version version = (Version) item;
                title = version.getName() + " " + version.getImageTypeDescription(resources);
            }
            else
            {
                Store store = (Store) item;
                title = store.getName();
            }
        }
        return title;
    }

    public static boolean isDeviceUnsupported(Context context)
    {
        Version deviceVersion = VersionParserHelper.getDeviceVersion(context);
        return deviceVersion == null || TextUtils.isEmpty(deviceVersion.getName());
    }

    private static Map<String,String> buildProps;
    public static Map<String,String> getpropAll(){

        if(buildProps==null) {
            buildProps = new HashMap<>();
            ProcessBuilder pb = new ProcessBuilder("/system/bin/getprop");
            pb.redirectErrorStream(true);
            Pattern propRegex = Pattern.compile("\\[([^\\]]+)\\]: \\[([^\\]]+)\\]");

            Process p;
            InputStream is = null;
            try {
                p = pb.start();
                is = p.getInputStream();
                Scanner scan = new Scanner(is);
                String prop;
                do {
                    prop = scan.nextLine();
                    Matcher match = propRegex.matcher(prop);
                    if(match.find()){
                        buildProps.put(match.group(1), match.group(2));
                    }
                } while(!prop.isEmpty());
            } catch (NoSuchElementException e) {
            } catch (IOException e) {
            }
        }
        return buildProps;
    }

    public static String getprop(String name, String defaultValue)
    {
        String result;
        if (getpropAll().containsKey(name)){
            result = getpropAll().get(name);
        } else {
            result = defaultValue;
        }
        return result;
    }

	public static void setBetaPropToEnable()
    {
        if(RootTools.isAccessGiven()) {
            CommandCapture command = new CommandCapture(0, "/system/bin/setprop "+ BetaEnabler.FAIRPHONE_BETA_PROPERTY+" "+BetaEnabler.BETA_ENABLED);
            try {
                Shell.runRootCommand(command);
            } catch (IOException | TimeoutException | RootDeniedException e) {
	            Log.d(TAG, "Failed to setprop: " + e.getLocalizedMessage());
            }
        }
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {

        }
        buildProps = null;
    }

    public static String getOtaPackagePath(Resources resources, DownloadableItem item, boolean isVersion, boolean isZipInstall){
        String path;

        if (Utils.hasUnifiedPartition(resources))
        {
            path = resources.getString(R.string.recoveryCachePath) + Utils.getFilenameFromDownloadableItem(item, isVersion);
        }
        else
        {
            if(isZipInstall && Build.MODEL.equalsIgnoreCase(resources.getString(R.string.FP1Model)))
            {
                //TODO: Find a way to not have this hardcoded
                String zipPath = item.getDownloadLink();
                path = zipPath.replace("/storage/sdcard0", resources.getString(R.string.recoverySdCardPath));
            }
            else
            {
                path = resources.getString(R.string.recoverySdCardPath) + resources.getString(R.string.updaterFolder) + Utils.getFilenameFromDownloadableItem(item, isVersion);
            }
        }

        return path;
    }

    public static void writeCacheCommand(Context context, String otaPackagePath) throws IOException, TimeoutException, RootDeniedException, Resources.NotFoundException {
        if (PrivilegeChecker.isPrivilegedApp()) {
            File recovery_dir = new File("/cache/recovery/");
            final boolean mkdirs = recovery_dir.mkdirs();
            if(! (mkdirs || recovery_dir.exists()) ) {
                String errorMessage = context.getResources().getString(R.string.failed_mkdirs_cache_message);
                Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show();
                throw new IOException(errorMessage);
            }

            File command = new File("/cache/recovery/command");
            File extendedCommand = new File("/cache/recovery/extendedcommand");
            final boolean deleteFailed = !extendedCommand.delete();
            if (deleteFailed) {
                Log.d(TAG, "Couldn't delete "+extendedCommand.getAbsolutePath());
            }

            String updateCommand = "--update_package=" + otaPackagePath;
            PrintWriter writer = new PrintWriter(command, "UTF-8");
            writer.println("--wipe_cache");
            writer.println(updateCommand);
            writer.flush();
            writer.close();
        }else {
            if(RootTools.isAccessGiven()) {
                Shell.runRootCommand(new CommandCapture(0, "rm -f /cache/recovery/command"));
                Shell.runRootCommand(new CommandCapture(0, "rm -f /cache/recovery/extendedcommand"));
                Shell.runRootCommand(new CommandCapture(0, "echo '--wipe_cache' >> /cache/recovery/command"));
                Shell.runRootCommand(new CommandCapture(0, "echo '--update_package=" + otaPackagePath + "' >> /cache/recovery/command"));
            }else{
                throw new RootDeniedException("Root Denied");
            }
        }
    }

    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    public static boolean rebootToRecovery(Context context) {
        boolean result;
        if (PrivilegeChecker.isPrivilegedApp()) {
            ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).reboot("recovery");
            result = false;
        } else {
            if(RootTools.isAccessGiven()) {
                try {
                    Shell.runRootCommand(new CommandCapture(0, "reboot recovery"));
                    result = true;
                } catch (IOException | TimeoutException | RootDeniedException e) {
                    Log.e(TAG, "Error rebooting to recovery: " + e.getLocalizedMessage());
                    result = false;
                }
            }else{
                result = false;
            }

        }
        return result;
    }
    
// --Commented out by Inspection START (06/02/2015 12:25):
//    public static void printStack(String moreLogs)
//    {
//        StringBuilder sb = new StringBuilder(moreLogs);
//        sb.append("\nStack --> ");
//        for (StackTraceElement ste : Thread.currentThread().getStackTrace())
//        {
//            sb.append(ste.getFileName()).append(" : ").append(ste.getMethodName()).append(":").append(ste.getLineNumber()).append(" -- ");
//        }
//        Log.wtf(TAG, sb.toString());
//    }
// --Commented out by Inspection STOP (06/02/2015 12:25)

    public static boolean fileExists(String otaPackagePath) {
        boolean fileExists;
        if(PrivilegeChecker.isPrivilegedApp()){
            File f = new File(otaPackagePath);
            fileExists = f.exists();
        }else {
            fileExists = RootTools.exists(otaPackagePath);
        }
        return fileExists;
    }

    private final static String[] SHELL_COMMANDS_ERASE_DATA = {
            // remove data
            "rm -rf /data/data/com.android.providers.media*",
            "rm -rf /data/data/com.android.keychain*",
            "rm -rf /data/data/com.android.location.fused*",
            "rm -rf /data/data/com.android.providers.applications*",
            "rm -rf /data/data/com.android.providers.media*",
            "rm -rf /data/data/com.android.vending*",
            "rm -rf /data/data/com.google.android.apps.genie.geniewidget*",
            "rm -rf /data/data/com.google.android.apps.plus*",
            "rm -rf /data/data/com.google.android.ears*",
            "rm -rf /data/data/com.google.android.gms*",
            "rm -rf /data/data/com.google.android.googlequicksearchbox*",
            "rm -rf /data/data/com.google.android.location*",
            "rm -rf /data/data/com.google.android.marvin.talkback*",
            // remove cache
//            "rm -rf /data/dalvik-cache",
            // remove data/app
            "rm -rf /data/app/com.android.apps.plus*",
            "rm -rf /data/app/com.android.vending*",
            "rm -rf /data/app/com.android.easr*",
            "rm -rf /data/app/com.android.gms*",
            "rm -rf /data/app/com.android.tts*"
    };

    public final static String SHELL_COMMAND_ERASE_DALVIK_CACHE = "rm -rf /data/dalvik-cache";
    public final static String SHELL_COMMAND_EXIT = "exit";

    public static void clearGappsData() throws RootDeniedException, IOException, InterruptedException {

        if (PrivilegeChecker.isPrivilegedApp()) {
            Process p = Runtime.getRuntime().exec(SHELL_COMMAND_ERASE_DALVIK_CACHE);
            DataOutputStream os = new DataOutputStream(p.getOutputStream());
            for (String tmpCmd : SHELL_COMMANDS_ERASE_DATA) {
                os.writeBytes(tmpCmd+"\n");
            }
            os.writeBytes(SHELL_COMMAND_EXIT+"\n");
            os.flush();
            p.waitFor();
        }else {
            if(RootTools.isAccessGiven()) {
                try {
                    Shell.runRootCommand(new CommandCapture(0, SHELL_COMMAND_ERASE_DALVIK_CACHE));
                } catch (TimeoutException e) {
                    e.printStackTrace();
                }
                for (String tmpCmd : SHELL_COMMANDS_ERASE_DATA) {
                    try {
                        Shell.runRootCommand(new CommandCapture(0, tmpCmd));
                    } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                }
            }else{
                throw new RootDeniedException("Root Denied");
            }
        }
    }

    public static String getPath(final Context context, final Uri uri)
    {
        String filePath = uri.getPath();
        if ("content".equalsIgnoreCase(uri.getScheme())) {

            //Get the zip file name
            String[] path = filePath.split("/");
            String downloadIdStr = "";
            if (path != null && path.length > 0) {
                downloadIdStr = path[path.length - 1];
            }
            long downloadId = 0;
            try {
                downloadId = Long.parseLong(downloadIdStr);
            } catch (NumberFormatException nfe) {
                Log.w(TAG, "NumberFormatException: " + nfe.getMessage());
            }

            DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
            DownloadManager.Query query = new DownloadManager.Query();

            query.setFilterById(downloadId);

            Cursor cursor = downloadManager != null ? downloadManager.query(query) : null;

            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
                int status = cursor.getInt(columnIndex);

                switch (status) {
                    case DownloadManager.STATUS_SUCCESSFUL: {
                        filePath = downloadManager.getUriForDownloadedFile(downloadId).getPath();
                        break;
                    }
                    case DownloadManager.STATUS_FAILED:
                    case DownloadManager.STATUS_PAUSED:
                    case DownloadManager.STATUS_PENDING:
                    case DownloadManager.STATUS_RUNNING:
                    default:
                        filePath = "";
                        break;
                }
            }
        }

        return filePath;
    }

	public static boolean isWiFiEnabled(Context context)
	{

		ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

		return manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();
	}

    public static Store getGappsStore()
    {
        return UpdaterData.getInstance().getStore(GAPPS_STORE_NUMBER);
    }
}
