/*
 * Copyright (C) 2016 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.
 */

#include "AST.h"

#include <android-base/logging.h>
#include <android-base/macros.h>
#include <set>
#include <map>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <vector>

using namespace android;

extern status_t parseFile(android::AST *ast);

static void usage(const char *me) {
    fprintf(stderr,
            "usage: %s [-g] [-o dir] -p package (-r interface-root)+ (header-filepath)+\n",
            me);

    fprintf(stderr, "         -h print this message\n");
    fprintf(stderr, "         -o output path\n");
    fprintf(stderr, "            (example: ~/android/master)\n");
    fprintf(stderr, "         -p package\n");
    fprintf(stderr, "            (example: android.hardware.baz@1.0)\n");
    fprintf(stderr, "         -g (enable open-gl mode) \n");
    fprintf(stderr, "         -r package:path root "
                    "(e.g., android.hardware:hardware/interfaces)\n");
}

static void addPackageRootToMap(const std::string &val,
                                std::map<std::string, std::string> &packageRootPaths) {
    auto index = val.find_first_of(':');
    CHECK(index != std::string::npos);

    auto package = val.substr(0, index);
    auto path = val.substr(index + 1);

    packageRootPaths[package] = path;
}

static bool isPathPrefix(const std::string &prefix, const std::string &base) {
    if (prefix.size() >= base.size()) {
        LOG(DEBUG) << "Not long enough";
        return false;
    }

    if (base[prefix.size()] != '.') {
        LOG(DEBUG) << "not full";
        return false;
    }

    return prefix == base.substr(0, prefix.size());
}

static void applyPackageRootPath(
        const std::map<std::string, std::string> &packageRootPaths,
        const std::string &package,
        std::string &outputPath) {

    auto index = package.find_first_of('@');
    CHECK(index != std::string::npos);

    auto packagePath = package.substr(0, index);
    auto packageVersion = package.substr(index + 1);

    for (auto const& pair : packageRootPaths) {
        const std::string& rootPackage = pair.first;
        const std::string& rootPath = pair.second;

        if (isPathPrefix(rootPackage, packagePath)) {

            packagePath = packagePath.substr(rootPackage.size() + 1);
            std::replace(packagePath.begin(), packagePath.end(), '.', '/');
            packagePath += '/' + packageVersion;

            if (outputPath.empty()) {
                outputPath = rootPath;
            }

            outputPath += '/' + packagePath + '/';
            return;
        }
    }

    CHECK(!outputPath.empty()) << "No package root path provided for: " << package;

    outputPath += '/';
}

// c2hal is intentionally leaky. Turn off LeakSanitizer by default.
extern "C" const char* __asan_default_options() {
    return "detect_leaks=0";
}

int main(int argc, char **argv) {
    const char *me = argv[0];

    std::string outputDir;
    std::string package;
    std::map<std::string, std::string> packageRootPaths;
    bool isOpenGl = false;
    bool verbose = false;

    int res;
    while ((res = getopt(argc, argv, "ghvo:p:r:")) >= 0) {
        switch (res) {
            case 'o': {
                outputDir = optarg;
                break;
            }
            case 'p': {
                package = optarg;
                break;
            }
            case 'g': {
                isOpenGl = true;
                break;
            }
            case 'v': {
                verbose = true;
                break;
            }
            case 'r':
            {
                addPackageRootToMap(optarg, packageRootPaths);
                break;
            }
            case 'h':
            default:
            {
                usage(me);
                exit(1);
                break;
            }
        }
    }

    // if no arguments are provided, show usage instead of specific errors
    if (optind == 1) {
        usage(me);
        exit(0);
    }

    if (verbose) {
        SetMinimumLogSeverity(android::base::VERBOSE);
    }

    applyPackageRootPath(packageRootPaths, package, outputDir);

    if (package.empty()) {
        LOG(WARNING) << "You must provide a package.";
        usage(me);
        exit(0);
    }

    if (optind == argc) {
        LOG(WARNING) << "You must provide a header-filepath.";
        usage(me);
        exit(0);
    }

    for(int i = optind; i < argc; i++) {
        std::string path = argv[i];

        LOG(DEBUG) << "Processing " << path;

        AST ast(path, outputDir, package, isOpenGl);

        int res = parseFile(&ast);

        if (res != 0) {
            LOG(ERROR) << "Could not parse: " << res;
            exit(1);
        }

        ast.processContents();

        ast.generateCode();
    }

    return 0;
}
