/*
 * Copyright (C) 2017 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.
 */

#ifndef REFERENCE_H_

#define REFERENCE_H_

#include <android-base/logging.h>
#include <hidl-util/FQName.h>

#include <string>

#include "DocComment.h"
#include "Location.h"

namespace android {

/**
 * Reference placeholder
 */
template <class T>
struct Reference {
    Reference() = default;
    virtual ~Reference() {}

    Reference(const std::string& localName, const FQName& fqName, const Location& location,
              bool definedInline = false)
        : mResolved(nullptr),
          mFqName(fqName),
          mLocation(location),
          mDefinedInline(definedInline),
          mLocalName(localName) {}

    Reference(const std::string& localName, T* type, const Location& location,
              bool definedInline = false)
        : mResolved(type),
          mLocation(location),
          mDefinedInline(definedInline),
          mLocalName(localName) {
        CHECK(type != nullptr);
    }

    template <class OtherT>
    Reference(const Reference<OtherT>& ref)
        : mResolved(ref.mResolved),
          mFqName(ref.mFqName),
          mLocation(ref.mLocation),
          mDefinedInline(ref.mDefinedInline),
          mLocalName(ref.mLocalName) {}

    template <class OtherT>
    Reference(const Reference<OtherT>& ref, const Location& location)
        : mResolved(ref.mResolved),
          mFqName(ref.mFqName),
          mLocation(location),
          mDefinedInline(ref.mDefinedInline),
          mLocalName(ref.mLocalName) {}

    /* Returns true iff referred type is resolved
       Referred type's field might be not resolved */
    bool isResolved() const { return mResolved != nullptr; }

    T* operator->() { return get(); }
    const T* operator->() const { return get(); }

    /* Returns referenced object.
       If a type is referenced, all typedefs are unwrapped. */
    T* get() {
        CHECK(mResolved != nullptr);
        return mResolved->resolve();
    }
    const T* get() const {
        CHECK(mResolved != nullptr);
        return mResolved->resolve();
    }

    /* Returns exact referenced object.
       If a type is referenced, typedefs are not unwraped. */
    T* shallowGet() {
        CHECK(mResolved != nullptr);
        return mResolved;
    }
    const T* shallowGet() const {
        CHECK(mResolved != nullptr);
        return mResolved;
    }

    void set(T* resolved) {
        CHECK(!isResolved());
        CHECK(resolved != nullptr);
        mResolved = resolved;
    }

    /* Returns true iff this is reference to null:
       not resolved and has not name for lookup */
    bool isEmptyReference() const { return !isResolved() && !hasLookupFqName(); }

    const FQName& getLookupFqName() const {
        CHECK(hasLookupFqName());
        return mFqName;
    }

    bool hasLocation() const { return mLocation.isValid(); }

    const Location& location() const {
        CHECK(hasLocation());
        return mLocation;
    }

    bool definedInline() const { return mDefinedInline; }

    const std::string& localName() const { return mLocalName; }

  private:
    /* Referred type */
    T* mResolved = nullptr;
    /* Reference name for lookup */
    FQName mFqName;
    /* Reference location is mainly used for printing errors
       and handling forward reference restrictions */
    Location mLocation;
    /* definedInline is true if T is defined where it is referenced */
    bool mDefinedInline;

    /* Name used in the .hal file */
    std::string mLocalName;

    bool hasLookupFqName() const {
        // Valid only while not resolved to prevent confusion when
        // ref.hasLookupFqName() is false while ref,get()->fqName is valid.
        CHECK(!isResolved());
        return mFqName != FQName();
    }

    template <class OtherT>
    friend struct Reference;
};

template <class T>
struct NamedReference : public Reference<T>, DocCommentable {
    NamedReference(const std::string& name, const Reference<T>& reference, const Location& location)
        : Reference<T>(reference, location), mName(name) {}

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

    // TODO(b/64715470) Legacy
    const T& type() const { return *Reference<T>::get(); }

  private:
    const std::string mName;
};

}  // namespace android

#endif  // REFERENCE_H_
