/**
 * 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.broadcastradio.hal2;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.broadcastradio.V2_0.AmFmBandRange;
import android.hardware.broadcastradio.V2_0.AmFmRegionConfig;
import android.hardware.broadcastradio.V2_0.Announcement;
import android.hardware.broadcastradio.V2_0.DabTableEntry;
import android.hardware.broadcastradio.V2_0.IdentifierType;
import android.hardware.broadcastradio.V2_0.Metadata;
import android.hardware.broadcastradio.V2_0.MetadataKey;
import android.hardware.broadcastradio.V2_0.ProgramFilter;
import android.hardware.broadcastradio.V2_0.ProgramIdentifier;
import android.hardware.broadcastradio.V2_0.ProgramInfo;
import android.hardware.broadcastradio.V2_0.ProgramInfoFlags;
import android.hardware.broadcastradio.V2_0.ProgramListChunk;
import android.hardware.broadcastradio.V2_0.Properties;
import android.hardware.broadcastradio.V2_0.Result;
import android.hardware.broadcastradio.V2_0.VendorKeyValue;
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioMetadata;
import android.os.ParcelableException;
import android.util.Slog;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

class Convert {
    private static final String TAG = "BcRadio2Srv.convert";

    static void throwOnError(String action, int result) {
        switch (result) {
            case Result.OK:
                return;
            case Result.UNKNOWN_ERROR:
                throw new ParcelableException(new RuntimeException(action + ": UNKNOWN_ERROR"));
            case Result.INTERNAL_ERROR:
                throw new ParcelableException(new RuntimeException(action + ": INTERNAL_ERROR"));
            case Result.INVALID_ARGUMENTS:
                throw new IllegalArgumentException(action + ": INVALID_ARGUMENTS");
            case Result.INVALID_STATE:
                throw new IllegalStateException(action + ": INVALID_STATE");
            case Result.NOT_SUPPORTED:
                throw new UnsupportedOperationException(action + ": NOT_SUPPORTED");
            case Result.TIMEOUT:
                throw new ParcelableException(new RuntimeException(action + ": TIMEOUT"));
            default:
                throw new ParcelableException(new RuntimeException(
                        action + ": unknown error (" + result + ")"));
        }
    }

    static @NonNull ArrayList<VendorKeyValue>
    vendorInfoToHal(@Nullable Map<String, String> info) {
        if (info == null) return new ArrayList<>();

        ArrayList<VendorKeyValue> list = new ArrayList<>();
        for (Map.Entry<String, String> entry : info.entrySet()) {
            VendorKeyValue elem = new VendorKeyValue();
            elem.key = entry.getKey();
            elem.value = entry.getValue();
            if (elem.key == null || elem.value == null) {
                Slog.w(TAG, "VendorKeyValue contains null pointers");
                continue;
            }
            list.add(elem);
        }

        return list;
    }

    static @NonNull Map<String, String>
    vendorInfoFromHal(@Nullable List<VendorKeyValue> info) {
        if (info == null) return Collections.emptyMap();

        Map<String, String> map = new HashMap<>();
        for (VendorKeyValue kvp : info) {
            if (kvp.key == null || kvp.value == null) {
                Slog.w(TAG, "VendorKeyValue contains null pointers");
                continue;
            }
            map.put(kvp.key, kvp.value);
        }

        return map;
    }

    private static @ProgramSelector.ProgramType int identifierTypeToProgramType(
            @ProgramSelector.IdentifierType int idType) {
        switch (idType) {
            case ProgramSelector.IDENTIFIER_TYPE_AMFM_FREQUENCY:
            case ProgramSelector.IDENTIFIER_TYPE_RDS_PI:
                // TODO(b/69958423): verify AM/FM with frequency range
                return ProgramSelector.PROGRAM_TYPE_FM;
            case ProgramSelector.IDENTIFIER_TYPE_HD_STATION_ID_EXT:
                // TODO(b/69958423): verify AM/FM with frequency range
                return ProgramSelector.PROGRAM_TYPE_FM_HD;
            case ProgramSelector.IDENTIFIER_TYPE_DAB_SIDECC:
            case ProgramSelector.IDENTIFIER_TYPE_DAB_ENSEMBLE:
            case ProgramSelector.IDENTIFIER_TYPE_DAB_SCID:
            case ProgramSelector.IDENTIFIER_TYPE_DAB_FREQUENCY:
                return ProgramSelector.PROGRAM_TYPE_DAB;
            case ProgramSelector.IDENTIFIER_TYPE_DRMO_SERVICE_ID:
            case ProgramSelector.IDENTIFIER_TYPE_DRMO_FREQUENCY:
                return ProgramSelector.PROGRAM_TYPE_DRMO;
            case ProgramSelector.IDENTIFIER_TYPE_SXM_SERVICE_ID:
            case ProgramSelector.IDENTIFIER_TYPE_SXM_CHANNEL:
                return ProgramSelector.PROGRAM_TYPE_SXM;
        }
        if (idType >= ProgramSelector.IDENTIFIER_TYPE_VENDOR_PRIMARY_START
                && idType <= ProgramSelector.IDENTIFIER_TYPE_VENDOR_PRIMARY_END) {
            return idType;
        }
        return ProgramSelector.PROGRAM_TYPE_INVALID;
    }

    private static @NonNull int[]
    identifierTypesToProgramTypes(@NonNull int[] idTypes) {
        Set<Integer> pTypes = new HashSet<>();

        for (int idType : idTypes) {
            int pType = identifierTypeToProgramType(idType);

            if (pType == ProgramSelector.PROGRAM_TYPE_INVALID) continue;

            pTypes.add(pType);
            if (pType == ProgramSelector.PROGRAM_TYPE_FM) {
                // TODO(b/69958423): verify AM/FM with region info
                pTypes.add(ProgramSelector.PROGRAM_TYPE_AM);
            }
            if (pType == ProgramSelector.PROGRAM_TYPE_FM_HD) {
                // TODO(b/69958423): verify AM/FM with region info
                pTypes.add(ProgramSelector.PROGRAM_TYPE_AM_HD);
            }
        }

        return pTypes.stream().mapToInt(Integer::intValue).toArray();
    }

    private static @NonNull RadioManager.BandDescriptor[]
    amfmConfigToBands(@Nullable AmFmRegionConfig config) {
        if (config == null) return new RadioManager.BandDescriptor[0];

        int len = config.ranges.size();
        List<RadioManager.BandDescriptor> bands = new ArrayList<>(len);

        // Just a dummy value.
        int region = RadioManager.REGION_ITU_1;

        for (AmFmBandRange range : config.ranges) {
            FrequencyBand bandType = Utils.getBand(range.lowerBound);
            if (bandType == FrequencyBand.UNKNOWN) {
                Slog.e(TAG, "Unknown frequency band at " + range.lowerBound + "kHz");
                continue;
            }
            if (bandType == FrequencyBand.FM) {
                bands.add(new RadioManager.FmBandDescriptor(region, RadioManager.BAND_FM,
                    range.lowerBound, range.upperBound, range.spacing,

                    // TODO(b/69958777): stereo, rds, ta, af, ea
                    true, true, true, true, true
                ));
            } else {  // AM
                bands.add(new RadioManager.AmBandDescriptor(region, RadioManager.BAND_AM,
                    range.lowerBound, range.upperBound, range.spacing,

                    // TODO(b/69958777): stereo
                    true
                ));
            }
        }

        return bands.toArray(new RadioManager.BandDescriptor[bands.size()]);
    }

    private static @Nullable Map<String, Integer> dabConfigFromHal(
            @Nullable List<DabTableEntry> config) {
        if (config == null) return null;
        return config.stream().collect(Collectors.toMap(e -> e.label, e -> e.frequency));
    }

    static @NonNull RadioManager.ModuleProperties
    propertiesFromHal(int id, @NonNull String serviceName, @NonNull Properties prop,
            @Nullable AmFmRegionConfig amfmConfig, @Nullable List<DabTableEntry> dabConfig) {
        Objects.requireNonNull(serviceName);
        Objects.requireNonNull(prop);

        int[] supportedIdentifierTypes = prop.supportedIdentifierTypes.stream().
                mapToInt(Integer::intValue).toArray();
        int[] supportedProgramTypes = identifierTypesToProgramTypes(supportedIdentifierTypes);

        return new RadioManager.ModuleProperties(
                id,
                serviceName,

                // There is no Class concept in HAL 2.0.
                RadioManager.CLASS_AM_FM,

                prop.maker,
                prop.product,
                prop.version,
                prop.serial,

                /* HAL 2.0 only supports single tuner and audio source per
                 * HAL implementation instance. */
                1,      // numTuners
                1,      // numAudioSources
                false,  // isInitializationRequired
                false,  // isCaptureSupported

                amfmConfigToBands(amfmConfig),
                true,  // isBgScanSupported is deprecated
                supportedProgramTypes,
                supportedIdentifierTypes,
                dabConfigFromHal(dabConfig),
                vendorInfoFromHal(prop.vendorInfo)
        );
    }

    static void programIdentifierToHal(@NonNull ProgramIdentifier hwId,
            @NonNull ProgramSelector.Identifier id) {
        hwId.type = id.getType();
        hwId.value = id.getValue();
    }

    static @NonNull ProgramIdentifier programIdentifierToHal(
            @NonNull ProgramSelector.Identifier id) {
        ProgramIdentifier hwId = new ProgramIdentifier();
        programIdentifierToHal(hwId, id);
        return hwId;
    }

    static @Nullable ProgramSelector.Identifier programIdentifierFromHal(
            @NonNull ProgramIdentifier id) {
        if (id.type == IdentifierType.INVALID) return null;
        return new ProgramSelector.Identifier(id.type, id.value);
    }

    static @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector programSelectorToHal(
            @NonNull ProgramSelector sel) {
        android.hardware.broadcastradio.V2_0.ProgramSelector hwSel =
            new android.hardware.broadcastradio.V2_0.ProgramSelector();

        programIdentifierToHal(hwSel.primaryId, sel.getPrimaryId());
        Arrays.stream(sel.getSecondaryIds()).map(Convert::programIdentifierToHal).
                forEachOrdered(hwSel.secondaryIds::add);

        return hwSel;
    }

    static @NonNull ProgramSelector programSelectorFromHal(
            @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
        ProgramSelector.Identifier[] secondaryIds = sel.secondaryIds.stream().
                map(Convert::programIdentifierFromHal).map(Objects::requireNonNull).
                toArray(ProgramSelector.Identifier[]::new);

        return new ProgramSelector(
                identifierTypeToProgramType(sel.primaryId.type),
                Objects.requireNonNull(programIdentifierFromHal(sel.primaryId)),
                secondaryIds, null);
    }

    private enum MetadataType {
        INT, STRING
    }

    private static class MetadataDef {
        private MetadataType type;
        private String key;
        private MetadataDef(MetadataType type, String key) {
            this.type = type;
            this.key = key;
        }
    }

    private static final Map<Integer, MetadataDef> metadataKeys;
    static {
        metadataKeys = new HashMap<>();
        metadataKeys.put(MetadataKey.RDS_PS, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_RDS_PS));
        metadataKeys.put(MetadataKey.RDS_PTY, new MetadataDef(
                MetadataType.INT, RadioMetadata.METADATA_KEY_RDS_PTY));
        metadataKeys.put(MetadataKey.RBDS_PTY, new MetadataDef(
                MetadataType.INT, RadioMetadata.METADATA_KEY_RBDS_PTY));
        metadataKeys.put(MetadataKey.RDS_RT, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_RDS_RT));
        metadataKeys.put(MetadataKey.SONG_TITLE, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_TITLE));
        metadataKeys.put(MetadataKey.SONG_ARTIST, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_ARTIST));
        metadataKeys.put(MetadataKey.SONG_ALBUM, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_ALBUM));
        metadataKeys.put(MetadataKey.STATION_ICON, new MetadataDef(
                MetadataType.INT, RadioMetadata.METADATA_KEY_ICON));
        metadataKeys.put(MetadataKey.ALBUM_ART, new MetadataDef(
                MetadataType.INT, RadioMetadata.METADATA_KEY_ART));
        metadataKeys.put(MetadataKey.PROGRAM_NAME, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_PROGRAM_NAME));
        metadataKeys.put(MetadataKey.DAB_ENSEMBLE_NAME, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_ENSEMBLE_NAME));
        metadataKeys.put(MetadataKey.DAB_ENSEMBLE_NAME_SHORT, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT));
        metadataKeys.put(MetadataKey.DAB_SERVICE_NAME, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_SERVICE_NAME));
        metadataKeys.put(MetadataKey.DAB_SERVICE_NAME_SHORT, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_SERVICE_NAME_SHORT));
        metadataKeys.put(MetadataKey.DAB_COMPONENT_NAME, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_COMPONENT_NAME));
        metadataKeys.put(MetadataKey.DAB_COMPONENT_NAME_SHORT, new MetadataDef(
                MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_COMPONENT_NAME_SHORT));
    }

    private static @NonNull RadioMetadata metadataFromHal(@NonNull ArrayList<Metadata> meta) {
        RadioMetadata.Builder builder = new RadioMetadata.Builder();

        for (Metadata entry : meta) {
            MetadataDef keyDef = metadataKeys.get(entry.key);
            if (keyDef == null) {
                Slog.i(TAG, "Ignored unknown metadata entry: " + MetadataKey.toString(entry.key));
                continue;
            }
            if (keyDef.type == MetadataType.STRING) {
                builder.putString(keyDef.key, entry.stringValue);
            } else {  // MetadataType.INT
                /* Current java API use 32-bit values for int metadata,
                 * but we might change it in the future */
                builder.putInt(keyDef.key, (int)entry.intValue);
            }
        }

        return builder.build();
    }

    static @NonNull RadioManager.ProgramInfo programInfoFromHal(@NonNull ProgramInfo info) {
        Collection<ProgramSelector.Identifier> relatedContent = info.relatedContent.stream().
                map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
                collect(Collectors.toList());

        return new RadioManager.ProgramInfo(
                programSelectorFromHal(info.selector),
                programIdentifierFromHal(info.logicallyTunedTo),
                programIdentifierFromHal(info.physicallyTunedTo),
                relatedContent,
                info.infoFlags,
                info.signalQuality,
                metadataFromHal(info.metadata),
                vendorInfoFromHal(info.vendorInfo)
        );
    }

    static @NonNull ProgramFilter programFilterToHal(@Nullable ProgramList.Filter filter) {
        if (filter == null) filter = new ProgramList.Filter();

        ProgramFilter hwFilter = new ProgramFilter();

        filter.getIdentifierTypes().stream().forEachOrdered(hwFilter.identifierTypes::add);
        filter.getIdentifiers().stream().forEachOrdered(
            id -> hwFilter.identifiers.add(programIdentifierToHal(id)));
        hwFilter.includeCategories = filter.areCategoriesIncluded();
        hwFilter.excludeModifications = filter.areModificationsExcluded();

        return hwFilter;
    }

    static @NonNull ProgramList.Chunk programListChunkFromHal(@NonNull ProgramListChunk chunk) {
        Set<RadioManager.ProgramInfo> modified = chunk.modified.stream().
                map(info -> programInfoFromHal(info)).collect(Collectors.toSet());
        Set<ProgramSelector.Identifier> removed = chunk.removed.stream().
                map(id -> Objects.requireNonNull(programIdentifierFromHal(id))).
                collect(Collectors.toSet());

        return new ProgramList.Chunk(chunk.purge, chunk.complete, modified, removed);
    }

    public static @NonNull android.hardware.radio.Announcement announcementFromHal(
            @NonNull Announcement hwAnnouncement) {
        return new android.hardware.radio.Announcement(
            programSelectorFromHal(hwAnnouncement.selector),
            hwAnnouncement.type,
            vendorInfoFromHal(hwAnnouncement.vendorInfo)
        );
    }

    static <T> @Nullable ArrayList<T> listToArrayList(@Nullable List<T> list) {
        if (list == null) return null;
        if (list instanceof ArrayList) return (ArrayList) list;
        return new ArrayList<>(list);
    }
}
