/*
 * 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(int fd) : mFD(fd) {}

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

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

  private:
    int mFD;
};

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, int in, int out, int err) {
    AdbFdTextOutput oin(out);
    AdbFdTextOutput oerr(err);
    return cmdMain(parseCmdArgs(args), oin, oerr, in, out, err, 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;
        }
    }
}
