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

#include "Method.h"

#include "Annotation.h"
#include "ConstantExpression.h"
#include "FormattingConstants.h"
#include "Reference.h"
#include "ScalarType.h"
#include "Type.h"

#include <android-base/logging.h>
#include <hidl-util/FQName.h>
#include <hidl-util/Formatter.h>
#include <algorithm>
#include <string>
#include <vector>

namespace android {

Method::Method(const std::string& name, std::vector<NamedReference<Type>*>* args,
               std::vector<NamedReference<Type>*>* results, bool oneway,
               std::vector<Annotation*>* annotations, const Location& location)
    : mName(name),
      mArgs(args),
      mResults(results),
      mOneway(oneway),
      mAnnotations(annotations),
      mLocation(location) {}

void Method::fillImplementation(
        size_t serial,
        MethodImpl cppImpl,
        MethodImpl javaImpl) {
    mIsHidlReserved = true;
    mSerial = serial;
    mCppImpl = cppImpl;
    mJavaImpl = javaImpl;

    CHECK(mJavaImpl.find(IMPL_STUB_IMPL) == mJavaImpl.end())
            << "FATAL: mJavaImpl should not use IMPL_STUB_IMPL; use IMPL_INTERFACE instead.";
    CHECK(mCppImpl.find(IMPL_STUB_IMPL) == mCppImpl.end() ||
          mCppImpl.find(IMPL_STUB) == mCppImpl.end())
            << "FATAL: mCppImpl IMPL_STUB will override IMPL_STUB_IMPL.";
}

std::string Method::name() const {
    return mName;
}

const std::vector<NamedReference<Type>*>& Method::args() const {
    return *mArgs;
}

const std::vector<NamedReference<Type>*>& Method::results() const {
    return *mResults;
}

const std::vector<Annotation *> &Method::annotations() const {
    return *mAnnotations;
}

std::vector<Reference<Type>*> Method::getReferences() {
    const auto& constRet = static_cast<const Method*>(this)->getReferences();
    std::vector<Reference<Type>*> ret(constRet.size());
    std::transform(constRet.begin(), constRet.end(), ret.begin(),
                   [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
    return ret;
}

std::vector<const Reference<Type>*> Method::getReferences() const {
    std::vector<const Reference<Type>*> ret;
    ret.insert(ret.end(), mArgs->begin(), mArgs->end());
    ret.insert(ret.end(), mResults->begin(), mResults->end());
    return ret;
}

std::vector<Reference<Type>*> Method::getStrongReferences() {
    const auto& constRet = static_cast<const Method*>(this)->getStrongReferences();
    std::vector<Reference<Type>*> ret(constRet.size());
    std::transform(constRet.begin(), constRet.end(), ret.begin(),
                   [](const auto* ref) { return const_cast<Reference<Type>*>(ref); });
    return ret;
}

std::vector<const Reference<Type>*> Method::getStrongReferences() const {
    std::vector<const Reference<Type>*> ret;
    for (const auto* ref : getReferences()) {
        if (!ref->shallowGet()->isNeverStrongReference()) {
            ret.push_back(ref);
        }
    }
    return ret;
}

void Method::cppImpl(MethodImplType type, Formatter &out) const {
    CHECK(mIsHidlReserved);
    auto it = mCppImpl.find(type);
    if (it != mCppImpl.end()) {
        if (it->second != nullptr) {
            it->second(out);
        }
    }
}

void Method::javaImpl(MethodImplType type, Formatter &out) const {
    CHECK(mIsHidlReserved);
    auto it = mJavaImpl.find(type);
    if (it != mJavaImpl.end()) {
        if (it->second != nullptr) {
            it->second(out);
        }
    }
}

bool Method::overridesCppImpl(MethodImplType type) const {
    CHECK(mIsHidlReserved);
    return mCppImpl.find(type) != mCppImpl.end();
}

bool Method::overridesJavaImpl(MethodImplType type) const {
    CHECK(mIsHidlReserved);
    return mJavaImpl.find(type) != mJavaImpl.end();
}

Method* Method::copySignature() const {
    Method* method = new Method(mName, mArgs, mResults, mOneway, mAnnotations, location());
    method->setDocComment(getDocComment());
    return method;
}

void Method::setSerialId(size_t serial) {
    CHECK(!mIsHidlReserved);
    mSerial = serial;
}

size_t Method::getSerialId() const {
    return mSerial;
}

bool Method::hasEmptyCppArgSignature() const {
    return args().empty() && (results().empty() || canElideCallback() != nullptr);
}

void Method::generateCppReturnType(Formatter &out, bool specifyNamespaces) const {
    const NamedReference<Type>* elidedReturn = canElideCallback();
    const std::string space = (specifyNamespaces ? "::android::hardware::" : "");

    if (elidedReturn == nullptr) {
        out << space << "Return<void> ";
    } else {
        out << space
            << "Return<"
            << elidedReturn->type().getCppResultType( specifyNamespaces)
            << "> ";
    }
}

void Method::generateCppSignature(Formatter &out,
                                  const std::string &className,
                                  bool specifyNamespaces) const {
    generateCppReturnType(out, specifyNamespaces);

    if (!className.empty()) {
        out << className << "::";
    }

    out << name()
        << "(";
    emitCppArgSignature(out, specifyNamespaces);
    out << ")";
}

static void emitCppArgResultSignature(Formatter& out,
                                      const std::vector<NamedReference<Type>*>& args,
                                      bool specifyNamespaces) {
    out.join(args.begin(), args.end(), ", ", [&](auto arg) {
        out << arg->type().getCppArgumentType(specifyNamespaces);
        out << " ";
        out << arg->name();
    });
}

static void emitJavaArgResultSignature(Formatter& out,
                                       const std::vector<NamedReference<Type>*>& args) {
    out.join(args.begin(), args.end(), ", ", [&](auto arg) {
        out << arg->type().getJavaType();
        out << " ";
        out << arg->name();
    });
}

void Method::emitCppArgSignature(Formatter &out, bool specifyNamespaces) const {
    emitCppArgResultSignature(out, args(), specifyNamespaces);

    const bool returnsValue = !results().empty();
    const NamedReference<Type>* elidedReturn = canElideCallback();
    if (returnsValue && elidedReturn == nullptr) {
        if (!args().empty()) {
            out << ", ";
        }

        out << name() << "_cb _hidl_cb";
    }
}
void Method::emitCppResultSignature(Formatter &out, bool specifyNamespaces) const {
    emitCppArgResultSignature(out, results(), specifyNamespaces);
}
void Method::emitJavaArgSignature(Formatter &out) const {
    emitJavaArgResultSignature(out, args());
}
void Method::emitJavaResultSignature(Formatter &out) const {
    emitJavaArgResultSignature(out, results());
}

void Method::emitJavaSignature(Formatter& out) const {
    const bool returnsValue = !results().empty();
    const bool needsCallback = results().size() > 1;

    if (returnsValue && !needsCallback) {
        out << results()[0]->type().getJavaType();
    } else {
        out << "void";
    }

    out << " " << name() << "(";
    emitJavaArgSignature(out);

    if (needsCallback) {
        if (!args().empty()) {
            out << ", ";
        }

        out << name() << "Callback _hidl_cb";
    }

    out << ")";
}

static void fillHidlArgResultTokens(const std::vector<NamedReference<Type>*>& args,
                                    WrappedOutput* wrappedOutput, const std::string& attachToLast) {
    for (size_t i = 0; i < args.size(); i++) {
        const NamedReference<Type>* arg = args[i];
        std::string out = arg->localName() + " " + arg->name();
        wrappedOutput->group([&] {
            if (i != 0) wrappedOutput->printUnlessWrapped(" ");
            *wrappedOutput << out;
            if (i == args.size() - 1) {
                if (!attachToLast.empty()) *wrappedOutput << attachToLast;
            } else {
                *wrappedOutput << ",";
            }
        });
    }
}

void Method::emitHidlDefinition(Formatter& out) const {
    if (getDocComment() != nullptr) getDocComment()->emit(out);

    out.join(mAnnotations->begin(), mAnnotations->end(), "\n",
             [&](auto annotation) { annotation->dump(out); });
    if (!mAnnotations->empty()) out << "\n";

    WrappedOutput wrappedOutput(MAX_LINE_LENGTH);

    if (isOneway()) wrappedOutput << "oneway ";
    wrappedOutput << name() << "(";

    if (!args().empty()) {
        fillHidlArgResultTokens(args(), &wrappedOutput, results().empty() ? ");\n" : ")");
    } else {
        wrappedOutput << (results().empty() ? ");\n" : ")");
    }

    if (!results().empty()) {
        wrappedOutput.group([&] {
            wrappedOutput.printUnlessWrapped(" ");
            wrappedOutput << "generates (";
            fillHidlArgResultTokens(results(), &wrappedOutput, ");\n");
        });
    }

    out << wrappedOutput;
}

bool Method::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
    if (!std::all_of(mArgs->begin(), mArgs->end(),
                     [&](const auto* arg) { return (*arg)->isJavaCompatible(visited); })) {
        return false;
    }

    if (!std::all_of(mResults->begin(), mResults->end(),
                     [&](const auto* arg) { return (*arg)->isJavaCompatible(visited); })) {
        return false;
    }

    return true;
}

const NamedReference<Type>* Method::canElideCallback() const {
    // Can't elide callback for void or tuple-returning methods
    if (mResults->size() != 1) {
        return nullptr;
    }

    const NamedReference<Type>* typedVar = mResults->at(0);

    if (typedVar->type().isElidableType()) {
        return typedVar;
    }

    return nullptr;
}

const Location& Method::location() const {
    return mLocation;
}

////////////////////////////////////////////////////////////////////////////////

bool TypedVarVector::add(NamedReference<Type>* v) {
    if (mNames.emplace(v->name()).second) {
        push_back(v);
        return true;
    }
    return false;
}

}  // namespace android

