package org.jruby;

import java.util.Map;

import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

public class IncludedModule extends RubyClass implements DelegatedModule {
    public IncludedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
        super(runtime, superClass, false);
        this.origin = origin;
        this.metaClass = origin.metaClass;
        if (superClass != null) {
            classIndex(superClass.getClassIndex()); // use same ClassIndex as metaclass, since we're technically still of that type
        }
    }

    @Override
    public boolean isModule() {
        return false;
    }

    @Override
    public boolean isClass() {
        return false;
    }

    @Override
    public boolean isImmediate() {
        return true;
    }

    @Override
    public void setMetaClass(RubyClass newRubyClass) {
        throw new UnsupportedOperationException("An included class is only a wrapper for a module");
    }

    @Override
    public String getName(ThreadContext context) {
        return origin.getName(context);
    }

    @Override
    public RubyModule getOrigin() {
        return origin;
    }

    @Deprecated(since = "10.0.3.0")
    @Override
    public IRubyObject id() {
        return origin.id();
    }

    /**
     * We don't want to reveal ourselves to Ruby code, so origin this
     * operation.
     */
    @Override
    public RubyInteger __id__(ThreadContext context) {
        return origin.__id__(context);
    }

    @Override
    protected synchronized Map<String, IRubyObject> getClassVariables() {
        return origin.getClassVariables();
    }

    @Override
    protected Map<String, IRubyObject> getClassVariablesForRead() {
        return origin.getClassVariablesForRead();
    }

    /** The module to which this include origins. */
    protected final RubyModule origin;
}