package com.android.defcontainer;

import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.PackageHelper;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.Package;
import android.net.Uri;
import android.os.Debug;
import android.os.Environment;
import android.os.IBinder;
import android.os.storage.IMountService;
import android.os.storage.StorageResultCode;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StatFs;
import android.app.IntentService;
import android.app.Service;
import android.util.DisplayMetrics;
import android.util.Log;

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.OutputStream;

import android.os.FileUtils;
import android.provider.Settings;

/*
 * This service copies a downloaded apk to a file passed in as
 * a ParcelFileDescriptor or to a newly created container specified
 * by parameters. The DownloadManager gives access to this process
 * based on its uid. This process also needs the ACCESS_DOWNLOAD_MANAGER
 * permission to access apks downloaded via the download manager.
 */
public class DefaultContainerService extends IntentService {
    private static final String TAG = "DefContainer";
    private static final boolean localLOGV = false;

    private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() {
        /*
         * Creates a new container and copies resource there.
         * @param paackageURI the uri of resource to be copied. Can be either
         * a content uri or a file uri
         * @param containerId the id of the secure container that should
         * be used for creating a secure container into which the resource
         * will be copied.
         * @param key Refers to key used for encrypting the secure container
         * @param resFileName Name of the target resource file(relative to newly
         * created secure container)
         * @return Returns the new cache path where the resource has been copied into
         *
         */
        public String copyResourceToContainer(final Uri packageURI,
                final String containerId,
                final String key, final String resFileName) {
            if (packageURI == null || containerId == null) {
                return null;
            }
            return copyResourceInner(packageURI, containerId, key, resFileName);
        }

        /*
         * Copy specified resource to output stream
         * @param packageURI the uri of resource to be copied. Should be a
         * file uri
         * @param outStream Remote file descriptor to be used for copying
         * @return Returns true if copy succeded or false otherwise.
         */
        public boolean copyResource(final Uri packageURI,
                ParcelFileDescriptor outStream) {
            if (packageURI == null ||  outStream == null) {
                return false;
            }
            ParcelFileDescriptor.AutoCloseOutputStream
            autoOut = new ParcelFileDescriptor.AutoCloseOutputStream(outStream);
            return copyFile(packageURI, autoOut);
        }

        /*
         * Determine the recommended install location for package
         * specified by file uri location.
         * @param fileUri the uri of resource to be copied. Should be a
         * file uri
         * @return Returns
         *  PackageHelper.RECOMMEND_INSTALL_INTERNAL to install on internal storage
         *  PackageHelper.RECOMMEND_INSTALL_EXTERNAL to install on external media
         *  PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE for storage errors
         *  PackageHelper.RECOMMEND_FAILED_INVALID_APK for parse errors.
         */
        public int getRecommendedInstallLocation(final Uri fileUri) {
            if (!fileUri.getScheme().equals("file")) {
                Log.w(TAG, "Falling back to installing on internal storage only");
                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
            }
            final String archiveFilePath = fileUri.getPath();
            PackageParser packageParser = new PackageParser(archiveFilePath);
            File sourceFile = new File(archiveFilePath);
            DisplayMetrics metrics = new DisplayMetrics();
            metrics.setToDefaults();
            PackageParser.Package pkg = packageParser.parsePackage(sourceFile, archiveFilePath, metrics, 0);
            if (pkg == null) {
                Log.w(TAG, "Failed to parse package");
                return PackageHelper.RECOMMEND_FAILED_INVALID_APK;
            }
            int loc = recommendAppInstallLocation(pkg);
            if (loc == PackageManager.INSTALL_EXTERNAL) {
                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
            } else if (loc == ERR_LOC) {
                Log.i(TAG, "Failed to install insufficient storage");
                return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
            } else {
                // Implies install on internal storage.
                return 0;
            }
        }
    };

    public DefaultContainerService() {
        super("DefaultContainerService");
        setIntentRedelivery(true);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) {
            IPackageManager pm = IPackageManager.Stub.asInterface(
                    ServiceManager.getService("package"));
            String pkg = null;
            try {
                while ((pkg=pm.nextPackageToClean(pkg)) != null) {
                    eraseFiles(Environment.getExternalStorageAppDataDirectory(pkg));
                    eraseFiles(Environment.getExternalStorageAppMediaDirectory(pkg));
                }
            } catch (RemoteException e) {
            }
        }
    }

    void eraseFiles(File path) {
        if (path.isDirectory()) {
            String[] files = path.list();
            if (files != null) {
                for (String file : files) {
                    eraseFiles(new File(path, file));
                }
            }
        }
        path.delete();
    }
    
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private IMountService getMountService() {
        return IMountService.Stub.asInterface(ServiceManager.getService("mount"));
    }

    private String copyResourceInner(Uri packageURI, String newCacheId, String key, String resFileName) {
        // Create new container at newCachePath
        String codePath = packageURI.getPath();
        String newCachePath = null;
        final int CREATE_FAILED = 1;
        final int COPY_FAILED = 2;
        final int FINALIZE_FAILED = 3;
        final int PASS = 4;
        int errCode = CREATE_FAILED;
        // Create new container
        if ((newCachePath = createSdDir(packageURI, newCacheId, key)) != null) {
            if (localLOGV) Log.i(TAG, "Created container for " + newCacheId
                    + " at path : " + newCachePath);
            File resFile = new File(newCachePath, resFileName);
            errCode = COPY_FAILED;
            // Copy file from codePath
            if (FileUtils.copyFile(new File(codePath), resFile)) {
                if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile);
                errCode = FINALIZE_FAILED;
                if (finalizeSdDir(newCacheId)) {
                    errCode = PASS;
                }
            }
        }
        // Print error based on errCode
        String errMsg = "";
        switch (errCode) {
            case CREATE_FAILED:
                errMsg = "CREATE_FAILED";
                break;
            case COPY_FAILED:
                errMsg = "COPY_FAILED";
                if (localLOGV) Log.i(TAG, "Destroying " + newCacheId +
                        " at path " + newCachePath + " after " + errMsg);
                destroySdDir(newCacheId);
                break;
            case FINALIZE_FAILED:
                errMsg = "FINALIZE_FAILED";
                if (localLOGV) Log.i(TAG, "Destroying " + newCacheId +
                        " at path " + newCachePath + " after " + errMsg);
                destroySdDir(newCacheId);
                break;
            default:
                errMsg = "PASS";
            if (localLOGV) Log.i(TAG, "Unmounting " + newCacheId +
                    " at path " + newCachePath + " after " + errMsg);
                unMountSdDir(newCacheId);
                break;
        }
        if (errCode != PASS) {
            return null;
        }
        return newCachePath;
    }

    private String createSdDir(final Uri packageURI,
            String containerId, String sdEncKey) {
        File tmpPackageFile = new File(packageURI.getPath());
        // Create mount point via MountService
        IMountService mountService = getMountService();
        long len = tmpPackageFile.length();
        int mbLen = (int) (len/(1024*1024));
        if ((len - (mbLen * 1024 * 1024)) > 0) {
            mbLen++;
        }
        if (localLOGV) Log.i(TAG, "mbLen=" + mbLen);
        String cachePath = null;
        int ownerUid = Process.myUid();
        try {
            int rc = mountService.createSecureContainer(
                    containerId, mbLen, "vfat", sdEncKey, ownerUid);

            if (rc != StorageResultCode.OperationSucceeded) {
                Log.e(TAG, String.format("Container creation failed (%d)", rc));

                // XXX: This destroy should not be necessary
                rc = mountService.destroySecureContainer(containerId);
                if (rc != StorageResultCode.OperationSucceeded) {
                    Log.e(TAG, String.format("Container creation-cleanup failed (%d)", rc));
                    return null;
                }

                // XXX: Does this ever actually succeed?
                rc = mountService.createSecureContainer(
                        containerId, mbLen, "vfat", sdEncKey, ownerUid);
                if (rc != StorageResultCode.OperationSucceeded) {
                    Log.e(TAG, String.format("Container creation retry failed (%d)", rc));
                }
            }

            cachePath = mountService.getSecureContainerPath(containerId);
            if (localLOGV) Log.i(TAG, "Trying to create secure container for  "
                    + containerId + ", cachePath =" + cachePath);
            return cachePath;
        } catch(RemoteException e) {
            Log.e(TAG, "MountService not running?");
            return null;
        }
    }

    private boolean destroySdDir(String containerId) {
        try {
            // We need to destroy right away
            getMountService().destroySecureContainer(containerId);
            return true;
        } catch (IllegalStateException e) {
            Log.i(TAG, "Failed to destroy container : " + containerId);
        } catch(RemoteException e) {
            Log.e(TAG, "MountService not running?");
        }
        return false;
    }

    private boolean finalizeSdDir(String containerId){
        try {
            getMountService().finalizeSecureContainer(containerId);
            return true;
        } catch (IllegalStateException e) {
            Log.i(TAG, "Failed to finalize container for pkg : " + containerId);
        } catch(RemoteException e) {
            Log.e(TAG, "MountService not running?");
        }
        return false;
    }

    private boolean unMountSdDir(String containerId) {
        try {
            getMountService().unmountSecureContainer(containerId);
            return true;
        } catch (IllegalStateException e) {
            Log.e(TAG, "Failed to unmount id:  " + containerId + " with exception " + e);
        } catch(RemoteException e) {
            Log.e(TAG, "MountService not running?");
        }
        return false;
    }

    private String mountSdDir(String containerId, String key) {
        try {
            int rc = getMountService().mountSecureContainer(containerId, key, Process.myUid());
            if (rc == StorageResultCode.OperationSucceeded) {
                return getMountService().getSecureContainerPath(containerId);
            } else {
                Log.e(TAG, String.format("Failed to mount id %s with rc %d ", containerId, rc));
            }
        } catch(RemoteException e) {
            Log.e(TAG, "MountService not running?");
        }
        return null;
    }

    public static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
        try {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) >= 0) {
                out.write(buffer, 0, bytesRead);
            }
            return true;
        } catch (IOException e) {
            Log.i(TAG, "Exception : " + e + " when copying file");
            return false;
        }
    }

    public static boolean copyToFile(File srcFile, FileOutputStream out) {
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(srcFile);
            return copyToFile(inputStream, out);
        } catch (IOException e) {
            return false;
        } finally {
            try { if (inputStream != null) inputStream.close(); } catch (IOException e) {}
        }
    }

    private  boolean copyFile(Uri pPackageURI, FileOutputStream outStream) {
        if (pPackageURI.getScheme().equals("file")) {
            final File srcPackageFile = new File(pPackageURI.getPath());
            // We copy the source package file to a temp file and then rename it to the
            // destination file in order to eliminate a window where the package directory
            // scanner notices the new package file but it's not completely copied yet.
            if (!copyToFile(srcPackageFile, outStream)) {
                Log.e(TAG, "Couldn't copy file: " + srcPackageFile);
                return false;
            }
        } else if (pPackageURI.getScheme().equals("content")) {
            ParcelFileDescriptor fd = null;
            try {
                fd = getContentResolver().openFileDescriptor(pPackageURI, "r");
            } catch (FileNotFoundException e) {
                Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e);
                return false;
            }
            if (fd == null) {
                Log.e(TAG, "Couldn't open file descriptor from download service (null).");
                return false;
            } else {
                if (localLOGV) {
                    Log.v(TAG, "Opened file descriptor from download service.");
                }
                ParcelFileDescriptor.AutoCloseInputStream
                dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd);
                // We copy the source package file to a temp file and then rename it to the
                // destination file in order to eliminate a window where the package directory
                // scanner notices the new package file but it's not completely copied yet.
                if (!copyToFile(dlStream, outStream)) {
                    Log.e(TAG, "Couldn't copy " + pPackageURI + " to temp file.");
                    return false;
                }
            }
        } else {
            Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
            return false;
        }
        return true;
    }

    // Constants related to app heuristics
    // No-installation limit for internal flash: 10% or less space available
    private static final double LOW_NAND_FLASH_TRESHOLD = 0.1;

    // SD-to-internal app size threshold: currently set to 1 MB
    private static final long INSTALL_ON_SD_THRESHOLD = (1024 * 1024);
    private static final int ERR_LOC = -1;

    public int recommendAppInstallLocation(Package pkg) {
        // Initial implementation:
        // Package size = code size + cache size + data size
        // If code size > 1 MB, install on SD card.
        // Else install on internal NAND flash, unless space on NAND is less than 10%

        if (pkg == null) {
            return ERR_LOC;
        }

        StatFs internalFlashStats = new StatFs(Environment.getDataDirectory().getPath());
        StatFs sdcardStats = new StatFs(Environment.getExternalStorageDirectory().getPath());

        long totalInternalFlashSize = (long)internalFlashStats.getBlockCount() *
                (long)internalFlashStats.getBlockSize();
        long availInternalFlashSize = (long)internalFlashStats.getAvailableBlocks() *
                (long)internalFlashStats.getBlockSize();
        long availSDSize = (long)sdcardStats.getAvailableBlocks() *
                (long)sdcardStats.getBlockSize();

        double pctNandFree = (double)availInternalFlashSize / (double)totalInternalFlashSize;

        final String archiveFilePath = pkg.mScanPath;
        File apkFile = new File(archiveFilePath);
        long pkgLen = apkFile.length();

        boolean auto = true;
        // To make final copy
        long reqInstallSize = pkgLen;
        // For dex files
        long reqInternalSize = 1 * pkgLen;
        boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
        boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
        boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
                (reqInternalSize < availInternalFlashSize);
        boolean fitsOnInt = intThresholdOk && intAvailOk;

        // Consider application flags preferences as well...
        boolean installOnlyOnSd = (pkg.installLocation ==
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
        boolean installOnlyInternal = (pkg.installLocation ==
                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
        if (installOnlyInternal) {
            // If set explicitly in manifest,
            // let that override everything else
            auto = false;
        } else if (installOnlyOnSd){
            // Check if this can be accommodated on the sdcard
            if (fitsOnSd) {
                auto = false;
            }
        } else {
            // Check if user option is enabled
            boolean setInstallLoc = Settings.System.getInt(getApplicationContext()
                    .getContentResolver(),
                    Settings.System.SET_INSTALL_LOCATION, 0) != 0;
            if (setInstallLoc) {
                // Pick user preference
                int installPreference = Settings.System.getInt(getApplicationContext()
                        .getContentResolver(),
                        Settings.System.DEFAULT_INSTALL_LOCATION,
                        PackageInfo.INSTALL_LOCATION_AUTO);
                if (installPreference == 1) {
                    installOnlyInternal = true;
                    auto = false;
                } else if (installPreference == 2) {
                    installOnlyOnSd = true;
                    auto = false;
                }
            }
        }
        if (!auto) {
            if (installOnlyOnSd) {
                return fitsOnSd ? PackageManager.INSTALL_EXTERNAL : ERR_LOC;
            } else if (installOnlyInternal){
                // Check on internal flash
                return fitsOnInt ? 0 : ERR_LOC;
            }
        }
        // Try to install internally
        if (fitsOnInt) {
            return 0;
        }
        // Try the sdcard now.
        if (fitsOnSd) {
            return PackageManager.INSTALL_EXTERNAL;
        }
        // Return error code
        return ERR_LOC;
    }

}
