/*
 * Copyright 2019 Fairphone B.V.
 *
 * 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.common;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import com.fairphone.common.crash.Crash;

import java.util.ArrayList;
import java.util.List;

final class CoreImpl extends Core {

    CoreImpl() {}

    /** {@inheritDoc} */
    @Override
    public void logcatStart(@NonNull @LogcatBuffer String... bufferNames) {
        // TODO: Start logcat logging
        return;
    }

    /** {@inheritDoc} */
    @Override
    public void logcatStop() {
        // TODO: Stop logcat logging
        return;
    }

    /** {@inheritDoc} */
    @Override
    public List<Crash> getCrashes() {
        List<Crash> crashes = new ArrayList<>();
        //TODO: Get all known crashes
        return crashes;
    }

    /** {@inheritDoc} */
    @Override
    public long getUptimeSinceLastSystemCrash() {
        // TODO: Get the cumulative system uptime since the last device reboot caused by a crash.
        return -1L;
    }

    /** {@inheritDoc} */
    @Override
    public long getUptimeSinceLastModemCrash() {
        // TODO: Get the cumulative modem uptime since the last modem reboot caused by a modem crash.
        return -1L;
    }

    /** {@inheritDoc} */
    @NonNull
    @Override
    public List<String> getModuleList() {
        List<String> modules = new ArrayList<>();
        //TODO: Get list of ModuleName
        return modules;
    }

    /** {@inheritDoc} */
    @Nullable
    @Override
    public List<String> getComponentList() {
        List<String> components = new ArrayList<>();
        //TODO: Get list of ComponentName
        return components;
    }

    /** {@inheritDoc} */
    @NonNull
    @Override
    public String getModuleId(@NonNull @ModuleName String module) {
        String id = null;

        switch(module) {
            case BATTERY_MODULE:
                //TODO: Get id
                break;
            case BOTTOM_MODULE:
                //TODO: Get id
                break;
            case CAMERA_MODULE:
                //TODO: Get id
                break;
            case CORE_MODULE:
                //TODO: Get id
                break;
            case DISPLAY_MODULE:
                //TODO: Get id
                break;
            case SPEAKER_MODULE:
                //TODO: Get id
                break;
            case TOP_MODULE:
                //TODO: Get id
                break;
            default:
                Log.e(TAG, "Unhandled module: " + module);
                break;
        }

        return id;
    }

    /** {@inheritDoc} */
    @Nullable
    @Override
    public String getModuleInfo(@NonNull @ModuleName String module) {
        String description = null;

        switch(module) {
            case BATTERY_MODULE:
                //TODO: Get description
                break;
            case BOTTOM_MODULE:
                //TODO: Get description
                break;
            case CAMERA_MODULE:
                //TODO: Get description
                break;
            case CORE_MODULE:
                //TODO: Get description
                break;
            case DISPLAY_MODULE:
                //TODO: Get description
                break;
            case SPEAKER_MODULE:
                //TODO: Get description
                break;
            case TOP_MODULE:
                //TODO: Get description
                break;
            default:
                Log.e(TAG, "Unhandled module: " + module);
                break;
        }

        return description;
    }

    /** {@inheritDoc} */
    @Nullable
    @Override
    public String getComponentId(@NonNull @ComponentName String component) {
        String id = null;

        switch(component) {
            case BASEBAND_PROCESSOR:
                //TODO: Get id
                break;
            case CPU:
                //TODO: Get id
                break;
            case FINGERPRINT:
                //TODO: Get id
                break;
            case FRONT_CAMERA:
                //TODO: Get id
                break;
            case MEMORY:
                //TODO: Get id
                break;
            case NFC:
                //TODO: Get id
                break;
            case REAR_CAMERA:
                //TODO: Get id
                break;
            default:
                Log.e(TAG, "Unhandled component: " + component);
                break;
        }

        return id;
    }

    /** {@inheritDoc} */
    @Nullable
    @Override
    public String getComponentInfo(@NonNull @ComponentName String component) {
        String description = null;

        switch(component) {
            case BASEBAND_PROCESSOR:
                //TODO: Get extra
                break;
            case CPU:
                //TODO: Get extra
                break;
            case FINGERPRINT:
                //TODO: Get extra
                break;
            case FRONT_CAMERA:
                //TODO: Get extra
                break;
            case MEMORY:
                //TODO: Get extra
                break;
            case NFC:
                //TODO: Get extra
                break;
            case REAR_CAMERA:
                //TODO: Get extra
                break;
            default:
                Log.e(TAG, "Unhandled component: " + component);
                break;
        }

        return description;
    }
}
