/*
 * Copyright (C) 2021 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 android.car.cts.powerpolicy;

import com.android.tradefed.log.LogUtil.CLog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;

public final class CpmsFrameworkLayerStateInfo {
    private static final int STRING_BUILDER_BUF_SIZE = 1024;

    public static final String COMMAND = "dumpsys car_service --services"
            + " CarPowerManagementService";
    public static final String CURRENT_STATE_HDR = "mCurrentState:";
    public static final String CURRENT_POLICY_ID_HDR = "mCurrentPowerPolicyId:";
    public static final String PENDING_POLICY_ID_HDR = "mPendingPowerPolicyId:";
    public static final String CURRENT_POLICY_GROUP_ID_HDR = "mCurrentPowerPolicyGroupId:";
    public static final String NUMBER_POLICY_LISTENERS_HDR = "# of power policy change listener:";
    public static final String POWER_POLICY_GROUPS_HDR = "Power policy groups:";
    public static final String PREEMPTIVE_POWER_POLICY_HDR = "Preemptive power policy:";
    public static final String COMPONENT_STATE_HDR = "Power components state:";
    public static final String COMPONENT_CONTROLLED_HDR =
            "Components powered off by power policy:";
    public static final String COMPONENT_CHANGED_HDR = "Components changed by the last policy:";
    public static final String MONITORING_HW_HDR = "Monitoring HW state signal:";
    public static final String SILENT_MODE_BY_HW_HDR = "Silent mode by HW state signal:";
    public static final String FORCED_SILENT_MODE_HDR = "Forced silent mode:";

    private static final String[] COMPONENT_LIST = {"AUDIO", "MEDIA", "DISPLAY", "BLUETOOTH",
            "WIFI", "CELLULAR", "ETHERNET", "PROJECTION", "NFC", "INPUT", "VOICE_INTERACTION",
            "VISUAL_INTERACTION", "TRUSTED_DEVICE_DETECTION", "LOCATION", "MICROPHONE", "CPU"};
    private static final HashSet COMPONENT_SET = new HashSet(Arrays.asList(COMPONENT_LIST));

    private final ArrayList<String> mEnables;
    private final ArrayList<String> mDisables;
    private final ArrayList<String> mControlledEnables;
    private final ArrayList<String> mControlledDisables;
    private final String[] mChangedComponents;
    private final PowerPolicyGroups mPowerPolicyGroups;
    private final String mCurrentPolicyId;
    private final String mPendingPolicyId;
    private final String mCurrentPolicyGroupId;
    private final int mNumberPolicyListeners;
    private final boolean mMonitoringHw;
    private final boolean mSilentModeByHw;
    private final boolean mForcedSilentMode;
    private final int mCurrentState;

    private CpmsFrameworkLayerStateInfo(String currentPolicyId, String pendingPolicyId,
            String currentPolicyGroupId, int numberPolicyListeners, String[] changedComponents,
            ArrayList<String> enables, ArrayList<String> disables, PowerPolicyGroups policyGroups,
            ArrayList<String> controlledEnables, ArrayList<String> controlledDisables,
            boolean monitoringHw, boolean silentModeByHw, boolean forcedSilentMode,
            int currentState) {
        mEnables = enables;
        mDisables = disables;
        mControlledEnables = controlledEnables;
        mControlledDisables = controlledDisables;
        mChangedComponents = changedComponents;
        mPowerPolicyGroups = policyGroups;
        mCurrentPolicyId = currentPolicyId;
        mPendingPolicyId = pendingPolicyId;
        mCurrentPolicyGroupId = currentPolicyGroupId;
        mNumberPolicyListeners = numberPolicyListeners;
        mMonitoringHw = monitoringHw;
        mSilentModeByHw = silentModeByHw;
        mForcedSilentMode = forcedSilentMode;
        mCurrentState = currentState;
    }

    public String getCurrentPolicyId() {
        return mCurrentPolicyId;
    }

    public String getPendingPolicyId() {
        return mPendingPolicyId;
    }

    public int getCurrentState() {
        return mCurrentState;
    }

    public boolean getForcedSilentMode() {
        return mForcedSilentMode;
    }

    public PowerPolicyDef.PowerComponent[] getCurrentEnabledComponents() {
        return PowerPolicyDef.PowerComponent.asComponentArray(mEnables);
    }

    public PowerPolicyDef.PowerComponent[] getCurrentDisabledComponents() {
        return PowerPolicyDef.PowerComponent.asComponentArray(mDisables);
    }

    public String getCurrentPolicyGroupId() {
        return mCurrentPolicyGroupId;
    }

    public PowerPolicyGroups getPowerPolicyGroups() {
        return mPowerPolicyGroups;
    }

    public int getNumberPolicyListeners() {
        return mNumberPolicyListeners;
    }

    public boolean isComponentOn(String component) {
        return mEnables.contains(component);
    }

    public boolean isComponentOff(String component) {
        return mDisables.contains(component);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(STRING_BUILDER_BUF_SIZE);
        sb.append("mCurrentState=").append(mCurrentState).append(' ');
        sb.append("mCurrentPolicyId=").append(mCurrentPolicyId).append(' ');
        sb.append("mPendingPolicyId=").append(mPendingPolicyId).append(' ');
        sb.append("mCurrentPolicyGroupId=").append(mCurrentPolicyGroupId).append(' ');
        sb.append("mNumberPolicyListeners=").append(mNumberPolicyListeners).append(' ');
        sb.append("silentmode=").append(mMonitoringHw).append(',');
        sb.append(mSilentModeByHw).append(',').append(mForcedSilentMode).append(' ');
        sb.append("enables=").append(String.join(",", mEnables)).append(' ');
        sb.append("disables=").append(String.join(",", mDisables));
        sb.append("controlledEnables=").append(String.join(",", mControlledEnables)).append(' ');
        sb.append("controlledDisables=").append(String.join(",", mControlledDisables));
        sb.append("changedComponents=").append(String.join(",", mChangedComponents));
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CpmsFrameworkLayerStateInfo that = (CpmsFrameworkLayerStateInfo) o;
        return mCurrentState == that.mCurrentState
                && mMonitoringHw == that.mMonitoringHw
                && mSilentModeByHw == that.mSilentModeByHw
                && mForcedSilentMode == that.mForcedSilentMode
                && mNumberPolicyListeners == that.mNumberPolicyListeners
                && mEnables.equals(that.mEnables)
                && mDisables.equals(that.mDisables)
                && mPowerPolicyGroups.equals(that.mPowerPolicyGroups)
                && mControlledEnables.equals(that.mControlledEnables)
                && mControlledDisables.equals(that.mControlledDisables)
                && Arrays.equals(mChangedComponents, that.mChangedComponents)
                && Objects.equals(mCurrentPolicyId, that.mCurrentPolicyId)
                && Objects.equals(mPendingPolicyId, that.mPendingPolicyId)
                && Objects.equals(mCurrentPolicyGroupId, that.mCurrentPolicyGroupId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mEnables, mDisables, mControlledEnables, mControlledDisables,
                mChangedComponents, mPowerPolicyGroups, mCurrentPolicyId, mPendingPolicyId,
                mCurrentPolicyGroupId, mCurrentState, mMonitoringHw, mSilentModeByHw,
                mForcedSilentMode, mNumberPolicyListeners);
    }

    public static CpmsFrameworkLayerStateInfo parse(String cmdOutput) throws Exception {
        int currentState = -1;
        String currentPolicyId = null;
        String pendingPolicyId = null;
        String currentPolicyGroupId = null;
        ArrayList<String> enables = null;
        ArrayList<String> disables = null;
        ArrayList<String> controlledEnables = null;
        ArrayList<String> controlledDisables = null;
        String[] changedComponents = null;
        PowerPolicyGroups policyGroups = null;
        boolean monitoringHw = false;
        boolean silentModeByHw = false;
        boolean forcedSilentMode = false;
        int numberPolicyListeners = 0;

        String[] lines = cmdOutput.split("\n");
        StateInfoParser parser = new StateInfoParser(lines);
        HashSet<String> headerCounter = new HashSet<String>();
        String header;
        while ((header = parser.searchHeader()) != null) {
            switch (header) {
                case CURRENT_STATE_HDR:
                    currentState = parser.getIntData(CURRENT_STATE_HDR);
                    break;
                case CURRENT_POLICY_ID_HDR:
                    currentPolicyId = parser.getStringData(CURRENT_POLICY_ID_HDR);
                    break;
                case PENDING_POLICY_ID_HDR:
                    pendingPolicyId = parser.getStringData(PENDING_POLICY_ID_HDR);
                    break;
                case CURRENT_POLICY_GROUP_ID_HDR:
                    currentPolicyGroupId = parser.getStringData(CURRENT_POLICY_GROUP_ID_HDR);
                    break;
                case POWER_POLICY_GROUPS_HDR:
                    ArrayList<String> groupList = parser.getStringArray(POWER_POLICY_GROUPS_HDR,
                            PREEMPTIVE_POWER_POLICY_HDR);
                    policyGroups = PowerPolicyGroups.parse(groupList);
                    break;
                case COMPONENT_STATE_HDR:
                    parser.parseComponentStates(COMPONENT_STATE_HDR,
                            COMPONENT_CONTROLLED_HDR, true);
                    enables = parser.getEnables();
                    disables = parser.getDisables();
                    Collections.sort(enables);
                    Collections.sort(disables);
                    break;
                case COMPONENT_CONTROLLED_HDR:
                    parser.parseComponentStates(COMPONENT_CONTROLLED_HDR,
                            COMPONENT_CHANGED_HDR, false);
                    controlledEnables = parser.getEnables();
                    controlledDisables = parser.getDisables();
                    Collections.sort(controlledEnables);
                    Collections.sort(controlledDisables);
                    break;
                case COMPONENT_CHANGED_HDR:
                    changedComponents = parser.getChangedComponents(COMPONENT_CHANGED_HDR,
                            MONITORING_HW_HDR);
                    break;
                case MONITORING_HW_HDR:
                    monitoringHw = parser.getBooleanData(MONITORING_HW_HDR);
                    break;
                case SILENT_MODE_BY_HW_HDR:
                    silentModeByHw = parser.getBooleanData(SILENT_MODE_BY_HW_HDR);
                    break;
                case FORCED_SILENT_MODE_HDR:
                    forcedSilentMode = parser.getBooleanData(FORCED_SILENT_MODE_HDR);
                    break;
                case NUMBER_POLICY_LISTENERS_HDR:
                    numberPolicyListeners = parser.getIntData(NUMBER_POLICY_LISTENERS_HDR);
                    break;
                default:
                    throw new IllegalArgumentException("parser header mismatch: " + header);
            }
            headerCounter.add(header);
        }

        if (headerCounter.size() != StateInfoParser.HEADERS.length) {
            String errMsg = "miss headers. got: " + headerCounter + " expected: "
                    + String.join(",", StateInfoParser.HEADERS);
            throw new IllegalArgumentException(errMsg);
        }

        return new CpmsFrameworkLayerStateInfo(currentPolicyId, pendingPolicyId,
                currentPolicyGroupId, numberPolicyListeners, changedComponents, enables,
                disables, policyGroups, controlledEnables, controlledDisables, monitoringHw,
                silentModeByHw, forcedSilentMode, currentState);
    }

    private static final class StateInfoParser {
        private static final String[] HEADERS = {
            CURRENT_STATE_HDR,
            CURRENT_POLICY_ID_HDR,
            PENDING_POLICY_ID_HDR,
            CURRENT_POLICY_GROUP_ID_HDR,
            NUMBER_POLICY_LISTENERS_HDR,
            COMPONENT_STATE_HDR,
            COMPONENT_CONTROLLED_HDR,
            POWER_POLICY_GROUPS_HDR,
            COMPONENT_CHANGED_HDR,
            MONITORING_HW_HDR,
            SILENT_MODE_BY_HW_HDR,
            FORCED_SILENT_MODE_HDR
        };
        private final String[] mLines;
        private ArrayList<String> mEnables;
        private ArrayList<String> mDisables;
        private int mIdx = 0;

        private StateInfoParser(String[] lines) {
            mLines = lines;
        }

        private ArrayList<String> getEnables() {
            return mEnables;
        }

        private ArrayList<String> getDisables() {
            return mDisables;
        }

        private int getIntData(String header) throws Exception {
            int val = 0;
            switch (header) {
                case CURRENT_STATE_HDR:
                    String[] tokens = mLines[mIdx].split(",*\\s");
                    if (tokens.length != 6) {
                        throw new IllegalArgumentException("malformatted mCurrentState: "
                                + mLines[mIdx]);
                    }
                    val = Integer.parseInt(tokens[4].trim().substring(tokens[4].length() - 1));
                    break;
                case NUMBER_POLICY_LISTENERS_HDR:
                    int strLen = mLines[mIdx].length();
                    val = Integer.parseInt(mLines[mIdx].substring(strLen - 1).trim());
                    break;
                default:
                    break;
            }
            return val;
        }

        private String getStringData(String header) {
            String val = null;
            if (mLines[mIdx].trim().length() != header.length()) {
                val = mLines[mIdx].trim().substring(header.length()).trim();
            }
            return val;
        }

        private ArrayList<String> getStringArray(String startHdr, String endHdr)
                throws Exception {
            if (!mLines[mIdx].contains(startHdr)) {
                String errMsg = String.format("expected start header %s at line %d : %s",
                        startHdr, mIdx, mLines[mIdx]);
                throw new IllegalArgumentException(errMsg);
            }

            ArrayList<String> strArray = new ArrayList<String>();
            while (++mIdx < mLines.length && !mLines[mIdx].contains(endHdr)) {
                strArray.add(mLines[mIdx]);
            }
            mIdx--;

            if (mIdx == (mLines.length - 1)) {
                throw new IllegalArgumentException("reaches the end while get " + startHdr);
            }
            return strArray;
        }

        private void parseComponentStates(String startHdr, String endHdr,
                boolean hasStateInfo) throws Exception {
            mEnables = new ArrayList<String>();
            mDisables = new ArrayList<String>();
            while (mIdx < (mLines.length - 1) && !mLines[++mIdx].contains(endHdr)) {
                String stateStr = mLines[mIdx].trim();
                String[] vals = stateStr.split(":\\s");
                if (hasStateInfo && vals.length != 2) {
                    String errMsg = String.format("wrong format at %d in: %s ", mIdx, stateStr);
                    CLog.e(errMsg);
                    throw new IllegalArgumentException(errMsg);
                }

                for (int i = 0; i < vals.length; i++) {
                    vals[i] = vals[i].trim();
                }

                if (!COMPONENT_SET.contains(vals[0])) {
                    String errMsg = String.format("invalid component at %d with %s in: %s",
                            mIdx, vals[0], stateStr);
                    CLog.e(errMsg);
                    throw new IllegalArgumentException(errMsg);
                }

                if (hasStateInfo) {
                    if (vals[1].startsWith("on")) {
                        mEnables.add(vals[0]);
                    } else if (vals[1].startsWith("off")) {
                        mDisables.add(vals[0]);
                    } else {
                        String errMsg =
                                String.format("wrong state value at %d with (%s, %s) in: %s",
                                mIdx, vals[0], vals[1], stateStr);
                        CLog.e(errMsg);
                        throw new IllegalArgumentException(errMsg);
                    }
                } else {
                    mDisables.add(vals[0]);
                }
            }
            mIdx--;

            if (mIdx == (mLines.length - 1)) {
                throw new IllegalArgumentException("reaches the end while parse " + startHdr);
            }
        }

        private String[] getChangedComponents(String startHdr, String endHdr) {
            int idx = mLines[mIdx].indexOf(endHdr);
            String compStr;
            if (idx < 0) {
                compStr = mLines[mIdx].substring(startHdr.length());
            } else {
                compStr = mLines[mIdx].substring(startHdr.length(), idx);
                mLines[mIdx] = mLines[mIdx].substring(idx);
                mIdx--;
            }
            return compStr.split(",\\s*");
        }

        private boolean getBooleanData(String header) {
            return Boolean.parseBoolean(mLines[mIdx].trim().substring(header.length()).trim());
        }

        private String searchHeader() {
            String header = null;
            for (mIdx++; mIdx < mLines.length; mIdx++) {
                if (mLines[mIdx].trim().isEmpty()) {
                    continue;
                }

                int firstHdrPos = mLines[mIdx].length() + 1;
                for (int i = 0; i < HEADERS.length; i++) {
                    int tempHdrPos = mLines[mIdx].indexOf(HEADERS[i]);
                    if (tempHdrPos >= 0 && (firstHdrPos > tempHdrPos)) {
                        firstHdrPos = tempHdrPos;
                        header = HEADERS[i];
                    }
                }
                if (header != null) {
                    break;
                }
            }

            return header;
        }
    }
}
