/*
 * 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.
 */
//#define LOG_NDEBUG 0
#define LOG_TAG "DataSource"


#include <datasource/DataSourceFactory.h>
#include <datasource/DataURISource.h>
#include <datasource/HTTPBase.h>
#include <datasource/FileSource.h>
#include <datasource/MediaHTTP.h>
#include <datasource/NuCachedSource2.h>
#include <media/MediaHTTPConnection.h>
#include <media/MediaHTTPService.h>
#include <utils/String8.h>

namespace android {

// static
sp<DataSourceFactory> DataSourceFactory::sInstance;
// static
Mutex DataSourceFactory::sInstanceLock;

// static
sp<DataSourceFactory> DataSourceFactory::getInstance() {
    Mutex::Autolock l(sInstanceLock);
    if (!sInstance) {
        sInstance = new DataSourceFactory();
    }
    return sInstance;
}

sp<DataSource> DataSourceFactory::CreateFromURI(
        const sp<MediaHTTPService> &httpService,
        const char *uri,
        const KeyedVector<String8, String8> *headers,
        String8 *contentType,
        HTTPBase *httpSource) {
    if (contentType != NULL) {
        *contentType = "";
    }

    sp<DataSource> source;
    if (!strncasecmp("file://", uri, 7)) {
        source = CreateFileSource(uri + 7);
    } else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
        if (httpService == NULL) {
            ALOGE("Invalid http service!");
            return NULL;
        }

        sp<HTTPBase> mediaHTTP = httpSource;
        if (mediaHTTP == NULL) {
            mediaHTTP = static_cast<HTTPBase *>(CreateMediaHTTP(httpService).get());
            if (mediaHTTP == NULL) {
                return NULL;
            }
        }

        String8 cacheConfig;
        bool disconnectAtHighwatermark = false;
        KeyedVector<String8, String8> nonCacheSpecificHeaders;
        if (headers != NULL) {
            nonCacheSpecificHeaders = *headers;
            NuCachedSource2::RemoveCacheSpecificHeaders(
                    &nonCacheSpecificHeaders,
                    &cacheConfig,
                    &disconnectAtHighwatermark);
        }

        if (mediaHTTP->connect(uri, &nonCacheSpecificHeaders) != OK) {
            ALOGE("Failed to connect http source!");
            return NULL;
        }

        if (contentType != NULL) {
            *contentType = mediaHTTP->getMIMEType();
        }

        source = NuCachedSource2::Create(
                mediaHTTP,
                cacheConfig.empty() ? NULL : cacheConfig.c_str(),
                disconnectAtHighwatermark);
    } else if (!strncasecmp("data:", uri, 5)) {
        source = DataURISource::Create(uri);
    } else {
        // Assume it's a filename.
        source = CreateFileSource(uri);
    }

    if (source == NULL || source->initCheck() != OK) {
        return NULL;
    }

    return source;
}

sp<DataSource> DataSourceFactory::CreateFromFd(int fd, int64_t offset, int64_t length) {
    sp<FileSource> source = new FileSource(fd, offset, length);
    return source->initCheck() != OK ? nullptr : source;
}

sp<DataSource> DataSourceFactory::CreateMediaHTTP(const sp<MediaHTTPService> &httpService) {
    if (httpService == NULL) {
        return NULL;
    }

    sp<MediaHTTPConnection> conn = httpService->makeHTTPConnection();
    if (conn == NULL) {
        ALOGE("Failed to make http connection from http service!");
        return NULL;
    } else {
        return new MediaHTTP(conn);
    }
}

sp<DataSource> DataSourceFactory::CreateFileSource(const char *uri) {
    return new FileSource(uri);
}

}  // namespace android
