/*
 * Copyright (C) 2019 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.content.type;

import libcore.content.type.MimeMap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;

/**
 * Creates the framework default {@link MimeMap}, a bidirectional mapping
 * between MIME types and file extensions.
 *
 * This default mapping is loaded from data files that start with some mappings
 * recognized by IANA plus some custom extensions and overrides.
 *
 * @hide
 */
public class DefaultMimeMapFactory {

    private DefaultMimeMapFactory() {
    }

    /**
     * Creates and returns a new {@link MimeMap} instance that implements.
     * Android's default mapping between MIME types and extensions.
     */
    public static MimeMap create() {
        Class c = DefaultMimeMapFactory.class;
        // The resources are placed into the res/ path by the "mimemap-res.jar" genrule.
        return create(resourceName -> c.getResourceAsStream("/res/" + resourceName));
    }

    /**
     * Creates a {@link MimeMap} instance whose resources are loaded from the
     * InputStreams looked up in {@code resourceSupplier}.
     *
     * @hide
     */
    public static MimeMap create(Function<String, InputStream> resourceSupplier) {
        MimeMap.Builder builder = MimeMap.builder();
        // The files loaded here must be in minimized format with lines of the
        // form "mime/type ext1 ext2 ext3", i.e. no comments, no empty lines, no
        // leading/trailing whitespace and with a single space between entries on
        // each line.  See http://b/142267887
        //
        // Note: the order here matters - later entries can overwrite earlier ones
        // (except that vendor.mime.types entries are prefixed with '?' which makes
        // them never overwrite).
        parseTypes(builder, resourceSupplier, "debian.mime.types");
        parseTypes(builder, resourceSupplier, "android.mime.types");
        parseTypes(builder, resourceSupplier, "vendor.mime.types");
        return builder.build();
    }

    private static void parseTypes(MimeMap.Builder builder,
            Function<String, InputStream> resourceSupplier, String resourceName) {
        try (InputStream inputStream = Objects.requireNonNull(resourceSupplier.apply(resourceName));
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            List<String> specs = new ArrayList<>(10); // re-use for each line
            while ((line = reader.readLine()) != null) {
                specs.clear();
                // Lines are of the form "mimeSpec extSpec extSpec[...]" with a single space
                // separating them and no leading/trailing spaces and no empty lines.
                int startIdx = 0;
                do {
                    int endIdx = line.indexOf(' ', startIdx);
                    if (endIdx < 0) {
                        endIdx = line.length();
                    }
                    String spec = line.substring(startIdx, endIdx);
                    if (spec.isEmpty()) {
                        throw new IllegalArgumentException("Malformed line: " + line);
                    }
                    specs.add(spec);
                    startIdx = endIdx + 1; // skip over the space
                } while (startIdx < line.length());
                builder.put(specs.get(0), specs.subList(1, specs.size()));
            }
        } catch (IOException | RuntimeException e) {
            throw new RuntimeException("Failed to parse " + resourceName, e);
        }
    }

}
