/*
 * Copyright (C) 2015 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 "sysdeps.h"

#include <stdio.h>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
#include <cutils/sockets.h>

#include "adb.h"
#include "adb_client.h"
#include "adb_io.h"
#include "adb_utils.h"

// Return the console authentication command for the emulator, if needed
static std::string adb_construct_auth_command() {
    static const char auth_token_filename[] = ".emulator_console_auth_token";

    std::string auth_token_path = adb_get_homedir_path(false);
    auth_token_path += OS_PATH_SEPARATOR;
    auth_token_path += auth_token_filename;

    // read the token
    std::string token;
    if (!android::base::ReadFileToString(auth_token_path, &token)
        || token.empty()) {
        // we either can't read the file, or it doesn't exist, or it's empty -
        // either way we won't add any authentication command.
        return {};
    }

    // now construct and return the actual command: "auth <token>\n"
    std::string command = "auth ";
    command += token;
    command += '\n';
    return command;
}

// Return the console port of the currently connected emulator (if any) or -1 if
// there is no emulator, and -2 if there is more than one.
static int adb_get_emulator_console_port(const char* serial) {
    if (serial) {
        // The user specified a serial number; is it an emulator?
        int port;
        return (sscanf(serial, "emulator-%d", &port) == 1) ? port : -1;
    }

    // No specific device was given, so get the list of connected devices and
    // search for emulators. If there's one, we'll take it. If there are more
    // than one, that's an error.
    std::string devices;
    std::string error;
    if (!adb_query("host:devices", &devices, &error)) {
        fprintf(stderr, "error: no emulator connected: %s\n", error.c_str());
        return -1;
    }

    int port;
    size_t emulator_count = 0;
    for (const auto& device : android::base::Split(devices, "\n")) {
        if (sscanf(device.c_str(), "emulator-%d", &port) == 1) {
            if (++emulator_count > 1) {
                fprintf(
                    stderr, "error: more than one emulator detected; use -s\n");
                return -1;
            }
        }
    }

    if (emulator_count == 0) {
        fprintf(stderr, "error: no emulator detected\n");
        return -1;
    }

    return port;
}

static int connect_to_console(const char* serial) {
    int port = adb_get_emulator_console_port(serial);
    if (port == -1) {
        return -1;
    }

    std::string error;
    int fd = network_loopback_client(port, SOCK_STREAM, &error);
    if (fd == -1) {
        fprintf(stderr, "error: could not connect to TCP port %d: %s\n", port,
                error.c_str());
        return -1;
    }
    return fd;
}

int adb_send_emulator_command(int argc, const char** argv, const char* serial) {
    int fd = connect_to_console(serial);
    if (fd == -1) {
        return 1;
    }

    std::string commands = adb_construct_auth_command();

    for (int i = 1; i < argc; i++) {
        commands.append(argv[i]);
        commands.push_back(i == argc - 1 ? '\n' : ' ');
    }

    commands.append("quit\n");

    if (!WriteFdExactly(fd, commands)) {
        fprintf(stderr, "error: cannot write to emulator: %s\n",
                strerror(errno));
        adb_close(fd);
        return 1;
    }

    // Drain output that the emulator console has sent us to prevent a problem
    // on Windows where if adb closes the socket without reading all the data,
    // the emulator's next call to recv() will have an ECONNABORTED error,
    // preventing the emulator from reading the command that adb has sent.
    // https://code.google.com/p/android/issues/detail?id=21021
    int result;
    do {
        char buf[BUFSIZ];
        result = adb_read(fd, buf, sizeof(buf));
        // Keep reading until zero bytes (orderly/graceful shutdown) or an
        // error. If 'adb emu kill' is executed, the emulator calls exit() with
        // the socket open (and shutdown(SD_SEND) was not called), which causes
        // Windows to send a TCP RST segment which causes adb to get ECONNRESET.
        // Any other emu command is followed by the quit command that we
        // appended above, and that causes the emulator to close the socket
        // which should cause zero bytes (orderly/graceful shutdown) to be
        // returned.
    } while (result > 0);

    adb_close(fd);

    return 0;
}
