/*
 * 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.icu.util.TimeZone;
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.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.getTimeZoneModuleTzVersionFile());
        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): "
                                    + TimeZone.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): "
                + TimeZone.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();
    }
}
