/*
 * Copyright (C) 2018 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 <sys/wait.h>

#include <android-base/cmsg.h>
#include <cmd.h>

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

namespace {

class AdbFdTextOutput : public android::TextOutput {
  public:
    explicit AdbFdTextOutput(borrowed_fd fd) : fd_(fd) {}

  private:
    android::status_t print(const char* txt, size_t len) override {
        return WriteFdExactly(fd_, txt, len) ? android::OK : -errno;
    }
    void moveIndent(int delta) override { /*not implemented*/
    }

    void pushBundle() override { /*not implemented*/
    }
    void popBundle() override { /*not implemented*/
    }

  private:
    borrowed_fd fd_;
};

std::vector<std::string_view> parseCmdArgs(std::string_view args) {
    std::vector<std::string_view> argv;

    char delim = ABB_ARG_DELIMETER;
    size_t size = args.size();
    size_t base = 0;
    while (base < size) {
        size_t found;
        for (found = base; found < size && args[found] && args[found] != delim; ++found)
            ;
        if (found > base) {
            argv.emplace_back(args.substr(base, found - base));
        }
        base = found + 1;
    }

    return argv;
}

}  // namespace

static int execCmd(std::string_view args, borrowed_fd in, borrowed_fd out, borrowed_fd err) {
    AdbFdTextOutput oin(out);
    AdbFdTextOutput oerr(err);
    return cmdMain(parseCmdArgs(args), oin, oerr, in.get(), out.get(), err.get(),
                   RunMode::kLibrary);
}

int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);

    int fd = STDIN_FILENO;
    std::string data;
    while (true) {
        std::string error;
        if (!ReadProtocolString(fd, &data, &error)) {
            PLOG(ERROR) << "Failed to read message: " << error;
            break;
        }

        std::string_view name = data;
        auto protocol = SubprocessProtocol::kShell;
        if (ConsumePrefix(&name, "abb:")) {
            protocol = SubprocessProtocol::kShell;
        } else if (ConsumePrefix(&name, "abb_exec:")) {
            protocol = SubprocessProtocol::kNone;
        } else {
            LOG(FATAL) << "Unknown command prefix for abb: " << data;
        }

        unique_fd result = StartCommandInProcess(std::string(name), &execCmd, protocol);
        if (android::base::SendFileDescriptors(fd, "", 1, result.get()) != 1) {
            PLOG(ERROR) << "Failed to send an inprocess fd for command: " << data;
            break;
        }
    }
}
