/*
 * Copyright (C) 2010 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 <utils/ObbFile.h>
#include <utils/String8.h>

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace android;

static const char* gProgName = "obbtool";
static const char* gProgVersion = "1.0";

static int wantUsage = 0;
static int wantVersion = 0;

#define SALT_LEN 8

#define ADD_OPTS "n:v:os:"
static const struct option longopts[] = {
    {"help",       no_argument, &wantUsage,   1},
    {"version",    no_argument, &wantVersion, 1},

    /* Args for "add" */
    {"name",       required_argument, NULL, 'n'},
    {"version",    required_argument, NULL, 'v'},
    {"overlay",    optional_argument, NULL, 'o'},
    {"salt",       required_argument, NULL, 's'},

    {NULL, 0, NULL, '\0'}
};

class PackageInfo {
public:
    PackageInfo()
            : packageName(NULL)
            , packageVersion(-1)
            , overlay(false)
            , salted(false)
    {
        memset(&salt, 0, sizeof(salt));
    }

    char* packageName;
    int packageVersion;
    bool overlay;
    bool salted;
    unsigned char salt[SALT_LEN];
};

/*
 * Print usage info.
 */
void usage(void)
{
    fprintf(stderr, "Opaque Binary Blob (OBB) Tool\n\n");
    fprintf(stderr, "Usage:\n");
    fprintf(stderr,
        " %s a[dd] [ OPTIONS ] FILENAME\n"
        "   Adds an OBB signature to the file.\n\n", gProgName);
    fprintf(stderr,
        "   Options:\n"
        "     -n <package name>      sets the OBB package name (required)\n"
        "     -v <OBB version>       sets the OBB version (required)\n"
        "     -o                     sets the OBB overlay flag\n"
        "     -s <8 byte hex salt>   sets the crypto key salt (if encrypted)\n"
        "\n");
    fprintf(stderr,
        " %s r[emove] FILENAME\n"
        "   Removes the OBB signature from the file.\n\n", gProgName);
    fprintf(stderr,
        " %s i[nfo] FILENAME\n"
        "   Prints the OBB signature information of a file.\n\n", gProgName);
}

void doAdd(const char* filename, struct PackageInfo* info) {
    ObbFile *obb = new ObbFile();
    if (obb->readFrom(filename)) {
        fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
        return;
    }

    obb->setPackageName(String8(info->packageName));
    obb->setVersion(info->packageVersion);
    obb->setOverlay(info->overlay);
    if (info->salted) {
        obb->setSalt(info->salt, SALT_LEN);
    }

    if (!obb->writeTo(filename)) {
        fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
                filename, strerror(errno));
        return;
    }

    fprintf(stderr, "OBB signature successfully written\n");
}

void doRemove(const char* filename) {
    ObbFile *obb = new ObbFile();
    if (!obb->readFrom(filename)) {
        fprintf(stderr, "ERROR: %s: no OBB signature present\n", filename);
        return;
    }

    if (!obb->removeFrom(filename)) {
        fprintf(stderr, "ERROR: %s: couldn't remove OBB signature\n", filename);
        return;
    }

    fprintf(stderr, "OBB signature successfully removed\n");
}

void doInfo(const char* filename) {
    ObbFile *obb = new ObbFile();
    if (!obb->readFrom(filename)) {
        fprintf(stderr, "ERROR: %s: couldn't read OBB signature\n", filename);
        return;
    }

    printf("OBB info for '%s':\n", filename);
    printf("Package name: %s\n", obb->getPackageName().string());
    printf("     Version: %d\n", obb->getVersion());
    printf("       Flags: 0x%08x\n", obb->getFlags());
    printf("     Overlay: %s\n", obb->isOverlay() ? "true" : "false");
    printf("        Salt: ");

    size_t saltLen;
    const unsigned char* salt = obb->getSalt(&saltLen);
    if (salt != NULL) {
        for (int i = 0; i < SALT_LEN; i++) {
            printf("%02x", salt[i]);
        }
        printf("\n");
    } else {
        printf("<empty>\n");
    }
}

bool fromHex(char h, unsigned char *b) {
    if (h >= '0' && h <= '9') {
        *b = h - '0';
        return true;
    } else if (h >= 'a' && h <= 'f') {
        *b = h - 'a' + 10;
        return true;
    } else if (h >= 'A' && h <= 'F') {
        *b = h - 'A' + 10;
        return true;
    }
    return false;
}

bool hexToByte(char h1, char h2, unsigned char* b) {
    unsigned char first, second;
    if (!fromHex(h1, &first)) return false;
    if (!fromHex(h2, &second)) return false;
    *b = (first << 4) | second;
    return true;
}

/*
 * Parse args.
 */
int main(int argc, char* const argv[])
{
    int opt;
    int option_index = 0;
    struct PackageInfo package_info;

    int result = 1;    // pessimistically assume an error.

    if (argc < 2) {
        wantUsage = 1;
        goto bail;
    }

    while ((opt = getopt_long(argc, argv, ADD_OPTS, longopts, &option_index)) != -1) {
        switch (opt) {
        case 0:
            if (longopts[option_index].flag)
                break;
            fprintf(stderr, "'%s' requires an argument\n", longopts[option_index].name);
            wantUsage = 1;
            goto bail;
        case 'n':
            package_info.packageName = optarg;
            break;
        case 'v': {
            char* end;
            package_info.packageVersion = strtol(optarg, &end, 10);
            if (*optarg == '\0' || *end != '\0') {
                fprintf(stderr, "ERROR: invalid version; should be integer!\n\n");
                wantUsage = 1;
                goto bail;
            }
            break;
        }
        case 'o':
            package_info.overlay = true;
            break;
        case 's':
            if (strlen(optarg) != SALT_LEN * 2) {
                fprintf(stderr, "ERROR: salt must be 8 bytes in hex (e.g., ABCD65031337D00D)\n\n");
                wantUsage = 1;
                goto bail;
            }

            package_info.salted = true;

            unsigned char b;
            for (int i = 0, j = 0; i < SALT_LEN; i++, j+=2) {
                if (!hexToByte(optarg[j], optarg[j+1], &b)) {
                    fprintf(stderr, "ERROR: salt must be in hex (e.g., ABCD65031337D00D)\n");
                    wantUsage = 1;
                    goto bail;
                }
                package_info.salt[i] = b;
            }
            break;
        case '?':
            wantUsage = 1;
            goto bail;
        }
    }

    if (wantVersion) {
        fprintf(stderr, "%s %s\n", gProgName, gProgVersion);
    }

    if (wantUsage) {
        goto bail;
    }

#define CHECK_OP(name) \
    if (strncmp(op, name, opsize)) { \
        fprintf(stderr, "ERROR: unknown function '%s'!\n\n", op); \
        wantUsage = 1; \
        goto bail; \
    }

    if (optind < argc) {
        const char* op = argv[optind++];
        const int opsize = strlen(op);

        if (optind >= argc) {
            fprintf(stderr, "ERROR: filename required!\n\n");
            wantUsage = 1;
            goto bail;
        }

        const char* filename = argv[optind++];

        switch (op[0]) {
        case 'a':
            CHECK_OP("add");
            if (package_info.packageName == NULL) {
                fprintf(stderr, "ERROR: arguments required 'packageName' and 'version'\n");
                goto bail;
            }
            doAdd(filename, &package_info);
            break;
        case 'r':
            CHECK_OP("remove");
            doRemove(filename);
            break;
        case 'i':
            CHECK_OP("info");
            doInfo(filename);
            break;
        default:
            fprintf(stderr, "ERROR: unknown command '%s'!\n\n", op);
            wantUsage = 1;
            goto bail;
        }
    }

bail:
    if (wantUsage) {
        usage();
        result = 2;
    }

    return result;
}
