/*
 * 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.
 */

#define LOG_TAG "dumpstate"

#include "DumpstateDevice.h"

#include "DumpstateUtil.h"

#include <errno.h>
#include <log/log.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

static const char base64[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char pad64 = '=';

using android::os::dumpstate::CommandOptions;
using android::os::dumpstate::DumpFileToFd;
using android::os::dumpstate::RunCommandToFd;

namespace android {
namespace hardware {
namespace dumpstate {
namespace V1_0 {
namespace implementation {

static void base64_output3(int out_fd, const unsigned char *src, int len)
{
    dprintf(out_fd, "%c", base64[src[0] >> 2]);
    dprintf(out_fd, "%c", base64[((src[0] & 0x03) << 4) | (src[1] >> 4)]);
    if (len == 1) {
        dprintf(out_fd, "==");
        return;
    }
    dprintf(out_fd, "%c", base64[((src[1] & 0x0F) << 2) | (src[2] >> 6)]);
    if (len == 2) {
        dprintf(out_fd, "=");
        return;
    }
    dprintf(out_fd, "%c", base64[src[2] & 0x3F]);
}

static void fugu_dump_base64(int out_fd, const char *path)
{

    dprintf(out_fd, "------ (%s) ------\n", path);
    int fd = open(path, O_RDONLY | O_CLOEXEC | O_NOFOLLOW);
    if (fd < 0) {
        dprintf(out_fd, "*** %s: %s\n\n", path, strerror(errno));
        return;
    }

    /* buffer size multiple of 3 for ease of use */
    unsigned char buffer[1200];
    int left = 0;
    int count = 0;
    for (;;) {
        int ret = read(fd, &buffer[left], sizeof(buffer) - left);
        if (ret <= 0) {
            break;
        }
        left += ret;
        int ofs = 0;
        while (left > 2) {
            base64_output3(out_fd, &buffer[ofs], 3);
            left -= 3;
            ofs += 3;
            count += 4;
            if (count > 72) {
                dprintf(out_fd, "\n");
                count = 0;
            }
        }
        if (left) {
            memmove(buffer, &buffer[ofs], left);
        }
    }
    close(fd);

    if (!left) {
        dprintf(out_fd, "\n------ end ------\n");
        return;
    }

    /* finish padding */
    count = left;
    while (count < 3) {
        buffer[count++] = 0;
    }
    base64_output3(out_fd, buffer, left);

    dprintf(out_fd, "\n------ end ------\n");
}

// Methods from ::android::hardware::dumpstate::V1_0::IDumpstateDevice follow.
Return<void> DumpstateDevice::dumpstateBoard(const hidl_handle& handle) {
    if (handle->numFds < 1) {
        ALOGE("no FDs\n");
        return Void();
    }

    int fd = handle->data[0];
    if (fd < 0) {
        ALOGE("invalid FD: %d\n", handle->data[0]);
        return Void();
    }

    DumpFileToFd(fd, "INTERRUPTS", "/proc/interrupts");
    DumpFileToFd(fd, "last ipanic_console", "/data/dontpanic/ipanic_console");
    DumpFileToFd(fd, "last ipanic_threads", "/data/dontpanic/ipanic_threads");

    fugu_dump_base64(fd, "/dev/snd_atvr_mSBC");
    fugu_dump_base64(fd, "/dev/snd_atvr_pcm");

    return Void();
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace dumpstate
}  // namespace hardware
}  // namespace android
