/*
 * Copyright (C) 2017 The Android Open Source 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.android.server.timezone;

import static android.app.timezone.RulesState.DISTRO_STATUS_INSTALLED;
import static android.app.timezone.RulesState.DISTRO_STATUS_NONE;
import static android.app.timezone.RulesState.DISTRO_STATUS_UNKNOWN;
import static android.app.timezone.RulesState.STAGED_OPERATION_INSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_NONE;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNINSTALL;
import static android.app.timezone.RulesState.STAGED_OPERATION_UNKNOWN;

import android.app.timezone.Callback;
import android.app.timezone.DistroFormatVersion;
import android.app.timezone.DistroRulesVersion;
import android.app.timezone.ICallback;
import android.app.timezone.IRulesManager;
import android.app.timezone.RulesManager;
import android.app.timezone.RulesState;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.timezone.distro.DistroException;
import com.android.timezone.distro.DistroVersion;
import com.android.timezone.distro.StagedDistroOperation;
import com.android.timezone.distro.TimeZoneDistro;
import com.android.timezone.distro.installer.TimeZoneDistroInstaller;

import libcore.icu.ICU;
import libcore.timezone.TimeZoneDataFiles;
import libcore.timezone.TimeZoneFinder;
import libcore.timezone.TzDataSetVersion;
import libcore.timezone.ZoneInfoDB;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicBoolean;

public final class RulesManagerService extends IRulesManager.Stub {

    private static final String TAG = "timezone.RulesManagerService";

    /** The distro format supported by this device. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final DistroFormatVersion DISTRO_FORMAT_VERSION_SUPPORTED =
            new DistroFormatVersion(
                    TzDataSetVersion.currentFormatMajorVersion(),
                    TzDataSetVersion.currentFormatMinorVersion());

    public static class Lifecycle extends SystemService {
        public Lifecycle(Context context) {
            super(context);
        }

        @Override
        public void onStart() {
            RulesManagerService service = RulesManagerService.create(getContext());
            service.start();

            // Publish the binder service so it can be accessed from other (appropriately
            // permissioned) processes.
            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, service);

            // Publish the service instance locally so we can use it directly from within the system
            // server from TimeZoneUpdateIdler.
            publishLocalService(RulesManagerService.class, service);
        }
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final String REQUIRED_UPDATER_PERMISSION =
            android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    static final String REQUIRED_QUERY_PERMISSION =
            android.Manifest.permission.QUERY_TIME_ZONE_RULES;

    private final AtomicBoolean mOperationInProgress = new AtomicBoolean(false);
    private final PermissionHelper mPermissionHelper;
    private final PackageTracker mPackageTracker;
    private final Executor mExecutor;
    private final RulesManagerIntentHelper mIntentHelper;
    private final TimeZoneDistroInstaller mInstaller;

    private static RulesManagerService create(Context context) {
        RulesManagerServiceHelperImpl helper = new RulesManagerServiceHelperImpl(context);
        File baseVersionFile = new File(TimeZoneDataFiles.getRuntimeModuleTzVersionFile());
        File tzDataDir = new File(TimeZoneDataFiles.getDataTimeZoneRootDir());
        return new RulesManagerService(
                helper /* permissionHelper */,
                helper /* executor */,
                helper /* intentHelper */,
                PackageTracker.create(context),
                new TimeZoneDistroInstaller(TAG, baseVersionFile, tzDataDir));
    }

    // A constructor that can be used by tests to supply mocked / faked dependencies.
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    RulesManagerService(PermissionHelper permissionHelper, Executor executor,
            RulesManagerIntentHelper intentHelper, PackageTracker packageTracker,
            TimeZoneDistroInstaller timeZoneDistroInstaller) {
        mPermissionHelper = permissionHelper;
        mExecutor = executor;
        mIntentHelper = intentHelper;
        mPackageTracker = packageTracker;
        mInstaller = timeZoneDistroInstaller;
    }

    public void start() {
        // Return value deliberately ignored: no action required on failure to start.
        mPackageTracker.start();
    }

    @Override // Binder call
    public RulesState getRulesState() {
        mPermissionHelper.enforceCallerHasPermission(REQUIRED_QUERY_PERMISSION);

        return getRulesStateInternal();
    }

    /** Like {@link #getRulesState()} without the permission check. */
    private RulesState getRulesStateInternal() {
        synchronized(this) {
            TzDataSetVersion baseVersion;
            try {
                baseVersion = mInstaller.readBaseVersion();
            } catch (IOException e) {
                Slog.w(TAG, "Failed to read base rules version", e);
                return null;
            }

            // Determine the installed distro state. This should be possible regardless of whether
            // there's an operation in progress.
            DistroVersion installedDistroVersion;
            int distroStatus = DISTRO_STATUS_UNKNOWN;
            DistroRulesVersion installedDistroRulesVersion = null;
            try {
                installedDistroVersion = mInstaller.getInstalledDistroVersion();
                if (installedDistroVersion == null) {
                    distroStatus = DISTRO_STATUS_NONE;
                    installedDistroRulesVersion = null;
                } else {
                    distroStatus = DISTRO_STATUS_INSTALLED;
                    installedDistroRulesVersion = new DistroRulesVersion(
                            installedDistroVersion.rulesVersion,
                            installedDistroVersion.revision);
                }
            } catch (DistroException | IOException e) {
                Slog.w(TAG, "Failed to read installed distro.", e);
            }

            boolean operationInProgress = this.mOperationInProgress.get();

            // Determine the staged operation status, if possible.
            DistroRulesVersion stagedDistroRulesVersion = null;
            int stagedOperationStatus = STAGED_OPERATION_UNKNOWN;
            if (!operationInProgress) {
                StagedDistroOperation stagedDistroOperation;
                try {
                    stagedDistroOperation = mInstaller.getStagedDistroOperation();
                    if (stagedDistroOperation == null) {
                        stagedOperationStatus = STAGED_OPERATION_NONE;
                    } else if (stagedDistroOperation.isUninstall) {
                        stagedOperationStatus = STAGED_OPERATION_UNINSTALL;
                    } else {
                        // Must be an install.
                        stagedOperationStatus = STAGED_OPERATION_INSTALL;
                        DistroVersion stagedDistroVersion = stagedDistroOperation.distroVersion;
                        stagedDistroRulesVersion = new DistroRulesVersion(
                                stagedDistroVersion.rulesVersion,
                                stagedDistroVersion.revision);
                    }
                } catch (DistroException | IOException e) {
                    Slog.w(TAG, "Failed to read staged distro.", e);
                }
            }
            return new RulesState(baseVersion.rulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
                    operationInProgress, stagedOperationStatus, stagedDistroRulesVersion,
                    distroStatus, installedDistroRulesVersion);
        }
    }

    @Override
    public int requestInstall(ParcelFileDescriptor distroParcelFileDescriptor,
            byte[] checkTokenBytes, ICallback callback) {

        boolean closeParcelFileDescriptorOnExit = true;
        try {
            mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);

            CheckToken checkToken = null;
            if (checkTokenBytes != null) {
                checkToken = createCheckTokenOrThrow(checkTokenBytes);
            }
            EventLogTags.writeTimezoneRequestInstall(toStringOrNull(checkToken));

            synchronized (this) {
                if (distroParcelFileDescriptor == null) {
                    throw new NullPointerException("distroParcelFileDescriptor == null");
                }
                if (callback == null) {
                    throw new NullPointerException("observer == null");
                }
                if (mOperationInProgress.get()) {
                    return RulesManager.ERROR_OPERATION_IN_PROGRESS;
                }
                mOperationInProgress.set(true);

                // Execute the install asynchronously.
                mExecutor.execute(
                        new InstallRunnable(distroParcelFileDescriptor, checkToken, callback));

                // The InstallRunnable now owns the ParcelFileDescriptor, so it will close it after
                // it executes (and we do not have to).
                closeParcelFileDescriptorOnExit = false;

                return RulesManager.SUCCESS;
            }
        } finally {
            // We should close() the local ParcelFileDescriptor we were passed if it hasn't been
            // passed to another thread to handle.
            if (distroParcelFileDescriptor != null && closeParcelFileDescriptorOnExit) {
                try {
                    distroParcelFileDescriptor.close();
                } catch (IOException e) {
                    Slog.w(TAG, "Failed to close distroParcelFileDescriptor", e);
                }
            }
        }
    }

    private class InstallRunnable implements Runnable {

        private final ParcelFileDescriptor mDistroParcelFileDescriptor;
        private final CheckToken mCheckToken;
        private final ICallback mCallback;

        InstallRunnable(ParcelFileDescriptor distroParcelFileDescriptor, CheckToken checkToken,
                ICallback callback) {
            mDistroParcelFileDescriptor = distroParcelFileDescriptor;
            mCheckToken = checkToken;
            mCallback = callback;
        }

        @Override
        public void run() {
            EventLogTags.writeTimezoneInstallStarted(toStringOrNull(mCheckToken));

            boolean success = false;
            // Adopt the ParcelFileDescriptor into this try-with-resources so it is closed
            // when we are done.
            try (ParcelFileDescriptor pfd = mDistroParcelFileDescriptor) {
                // The ParcelFileDescriptor owns the underlying FileDescriptor and we'll close
                // it at the end of the try-with-resources.
                final boolean isFdOwner = false;
                InputStream is = new FileInputStream(pfd.getFileDescriptor(), isFdOwner);

                TimeZoneDistro distro = new TimeZoneDistro(is);
                int installerResult = mInstaller.stageInstallWithErrorCode(distro);

                // Notify interested parties that something is staged.
                sendInstallNotificationIntentIfRequired(installerResult);

                int resultCode = mapInstallerResultToApiCode(installerResult);
                EventLogTags.writeTimezoneInstallComplete(toStringOrNull(mCheckToken), resultCode);
                sendFinishedStatus(mCallback, resultCode);

                // All the installer failure modes are currently non-recoverable and won't be
                // improved by trying again. Therefore success = true.
                success = true;
            } catch (Exception e) {
                Slog.w(TAG, "Failed to install distro.", e);
                EventLogTags.writeTimezoneInstallComplete(
                        toStringOrNull(mCheckToken), Callback.ERROR_UNKNOWN_FAILURE);
                sendFinishedStatus(mCallback, Callback.ERROR_UNKNOWN_FAILURE);
            } finally {
                // Notify the package tracker that the operation is now complete.
                mPackageTracker.recordCheckResult(mCheckToken, success);

                mOperationInProgress.set(false);
            }
        }

        private void sendInstallNotificationIntentIfRequired(int installerResult) {
            if (installerResult == TimeZoneDistroInstaller.INSTALL_SUCCESS) {
                mIntentHelper.sendTimeZoneOperationStaged();
            }
        }

        private int mapInstallerResultToApiCode(int installerResult) {
            switch (installerResult) {
                case TimeZoneDistroInstaller.INSTALL_SUCCESS:
                    return Callback.SUCCESS;
                case TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE:
                    return Callback.ERROR_INSTALL_BAD_DISTRO_STRUCTURE;
                case TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD:
                    return Callback.ERROR_INSTALL_RULES_TOO_OLD;
                case TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION:
                    return Callback.ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION;
                case TimeZoneDistroInstaller.INSTALL_FAIL_VALIDATION_ERROR:
                    return Callback.ERROR_INSTALL_VALIDATION_ERROR;
                default:
                    return Callback.ERROR_UNKNOWN_FAILURE;
            }
        }
    }

    @Override
    public int requestUninstall(byte[] checkTokenBytes, ICallback callback) {
        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);

        CheckToken checkToken = null;
        if (checkTokenBytes != null) {
            checkToken = createCheckTokenOrThrow(checkTokenBytes);
        }
        EventLogTags.writeTimezoneRequestUninstall(toStringOrNull(checkToken));
        synchronized(this) {
            if (callback == null) {
                throw new NullPointerException("callback == null");
            }

            if (mOperationInProgress.get()) {
                return RulesManager.ERROR_OPERATION_IN_PROGRESS;
            }
            mOperationInProgress.set(true);

            // Execute the uninstall asynchronously.
            mExecutor.execute(new UninstallRunnable(checkToken, callback));

            return RulesManager.SUCCESS;
        }
    }

    private class UninstallRunnable implements Runnable {

        private final CheckToken mCheckToken;
        private final ICallback mCallback;

        UninstallRunnable(CheckToken checkToken, ICallback callback) {
            mCheckToken = checkToken;
            mCallback = callback;
        }

        @Override
        public void run() {
            EventLogTags.writeTimezoneUninstallStarted(toStringOrNull(mCheckToken));
            boolean packageTrackerStatus = false;
            try {
                int uninstallResult = mInstaller.stageUninstall();

                // Notify interested parties that something is staged.
                sendUninstallNotificationIntentIfRequired(uninstallResult);

                packageTrackerStatus = (uninstallResult == TimeZoneDistroInstaller.UNINSTALL_SUCCESS
                        || uninstallResult == TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED);

                // Right now we just have Callback.SUCCESS / Callback.ERROR_UNKNOWN_FAILURE for
                // uninstall. All clients should be checking against SUCCESS. More granular failures
                // may be added in future.
                int callbackResultCode =
                        packageTrackerStatus ? Callback.SUCCESS : Callback.ERROR_UNKNOWN_FAILURE;
                EventLogTags.writeTimezoneUninstallComplete(
                        toStringOrNull(mCheckToken), callbackResultCode);
                sendFinishedStatus(mCallback, callbackResultCode);
            } catch (Exception e) {
                EventLogTags.writeTimezoneUninstallComplete(
                        toStringOrNull(mCheckToken), Callback.ERROR_UNKNOWN_FAILURE);
                Slog.w(TAG, "Failed to uninstall distro.", e);
                sendFinishedStatus(mCallback, Callback.ERROR_UNKNOWN_FAILURE);
            } finally {
                // Notify the package tracker that the operation is now complete.
                mPackageTracker.recordCheckResult(mCheckToken, packageTrackerStatus);

                mOperationInProgress.set(false);
            }
        }

        private void sendUninstallNotificationIntentIfRequired(int uninstallResult) {
            switch (uninstallResult) {
                case TimeZoneDistroInstaller.UNINSTALL_SUCCESS:
                    mIntentHelper.sendTimeZoneOperationStaged();
                    break;
                case TimeZoneDistroInstaller.UNINSTALL_NOTHING_INSTALLED:
                    mIntentHelper.sendTimeZoneOperationUnstaged();
                    break;
                case TimeZoneDistroInstaller.UNINSTALL_FAIL:
                default:
                    // No-op - unknown or nothing to notify about.
            }
        }
    }

    private void sendFinishedStatus(ICallback callback, int resultCode) {
        try {
            callback.onFinished(resultCode);
        } catch (RemoteException e) {
            Slog.e(TAG, "Unable to notify observer of result", e);
        }
    }

    @Override
    public void requestNothing(byte[] checkTokenBytes, boolean success) {
        mPermissionHelper.enforceCallerHasPermission(REQUIRED_UPDATER_PERMISSION);
        CheckToken checkToken = null;
        if (checkTokenBytes != null) {
            checkToken = createCheckTokenOrThrow(checkTokenBytes);
        }
        EventLogTags.writeTimezoneRequestNothing(toStringOrNull(checkToken));
        mPackageTracker.recordCheckResult(checkToken, success);
        EventLogTags.writeTimezoneNothingComplete(toStringOrNull(checkToken));
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!mPermissionHelper.checkDumpPermission(TAG, pw)) {
            return;
        }

        RulesState rulesState = getRulesStateInternal();
        if (args != null && args.length == 2) {
            // Formatting options used for automated tests. The format is less free-form than
            // the -format options, which are intended to be easier to parse.
            if ("-format_state".equals(args[0]) && args[1] != null) {
                for (char c : args[1].toCharArray()) {
                    switch (c) {
                        case 'p': {
                            // Report operation in progress
                            String value = "Unknown";
                            if (rulesState != null) {
                                value = Boolean.toString(rulesState.isOperationInProgress());
                            }
                            pw.println("Operation in progress: " + value);
                            break;
                        }
                        case 'b': {
                            // Report base rules version
                            String value = "Unknown";
                            if (rulesState != null) {
                                value = rulesState.getBaseRulesVersion();
                            }
                            pw.println("Base rules version: " + value);
                            break;
                        }
                        case 'c': {
                            // Report current installation state
                            String value = "Unknown";
                            if (rulesState != null) {
                                value = distroStatusToString(rulesState.getDistroStatus());
                            }
                            pw.println("Current install state: " + value);
                            break;
                        }
                        case 'i': {
                            // Report currently installed version
                            String value = "Unknown";
                            if (rulesState != null) {
                                DistroRulesVersion installedRulesVersion =
                                        rulesState.getInstalledDistroRulesVersion();
                                if (installedRulesVersion == null) {
                                    value = "<None>";
                                } else {
                                    value = installedRulesVersion.toDumpString();
                                }
                            }
                            pw.println("Installed rules version: " + value);
                            break;
                        }
                        case 'o': {
                            // Report staged operation type
                            String value = "Unknown";
                            if (rulesState != null) {
                                int stagedOperationType = rulesState.getStagedOperationType();
                                value = stagedOperationToString(stagedOperationType);
                            }
                            pw.println("Staged operation: " + value);
                            break;
                        }
                        case 't': {
                            // Report staged version (i.e. the one that will be installed next boot
                            // if the staged operation is an install).
                            String value = "Unknown";
                            if (rulesState != null) {
                                DistroRulesVersion stagedDistroRulesVersion =
                                        rulesState.getStagedDistroRulesVersion();
                                if (stagedDistroRulesVersion == null) {
                                    value = "<None>";
                                } else {
                                    value = stagedDistroRulesVersion.toDumpString();
                                }
                            }
                            pw.println("Staged rules version: " + value);
                            break;
                        }
                        case 'a': {
                            // Report the active rules version (i.e. the rules in use by the current
                            // process).
                            pw.println("Active rules version (ICU, ZoneInfoDB, TimeZoneFinder): "
                                    + ICU.getTZDataVersion() + ","
                                    + ZoneInfoDB.getInstance().getVersion() + ","
                                    + TimeZoneFinder.getInstance().getIanaVersion());
                            break;
                        }
                        default: {
                            pw.println("Unknown option: " + c);
                        }
                    }
                }
                return;
            }
        }

        pw.println("RulesManagerService state: " + toString());
        pw.println("Active rules version (ICU, ZoneInfoDB, TimeZoneFinder): "
                + ICU.getTZDataVersion() + ","
                + ZoneInfoDB.getInstance().getVersion() + ","
                + TimeZoneFinder.getInstance().getIanaVersion());
        pw.println("Distro state: " + rulesState.toString());
        mPackageTracker.dump(pw);
    }

    /**
     * Called when the device is considered idle.
     */
    void notifyIdle() {
        // No package has changed: we are just triggering because the device is idle and there
        // *might* be work to do.
        final boolean packageChanged = false;
        mPackageTracker.triggerUpdateIfNeeded(packageChanged);
    }

    @Override
    public String toString() {
        return "RulesManagerService{" +
                "mOperationInProgress=" + mOperationInProgress +
                '}';
    }

    private static CheckToken createCheckTokenOrThrow(byte[] checkTokenBytes) {
        CheckToken checkToken;
        try {
            checkToken = CheckToken.fromByteArray(checkTokenBytes);
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to read token bytes "
                    + Arrays.toString(checkTokenBytes), e);
        }
        return checkToken;
    }

    private static String distroStatusToString(int distroStatus) {
        switch(distroStatus) {
            case DISTRO_STATUS_NONE:
                return "None";
            case DISTRO_STATUS_INSTALLED:
                return "Installed";
            case DISTRO_STATUS_UNKNOWN:
            default:
                return "Unknown";
        }
    }

    private static String stagedOperationToString(int stagedOperationType) {
        switch(stagedOperationType) {
            case STAGED_OPERATION_NONE:
                return "None";
            case STAGED_OPERATION_UNINSTALL:
                return "Uninstall";
            case STAGED_OPERATION_INSTALL:
                return "Install";
            case STAGED_OPERATION_UNKNOWN:
            default:
                return "Unknown";
        }
    }

    private static String toStringOrNull(Object obj) {
        return obj == null ? null : obj.toString();
    }
}
