/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

package org.apache.ignite.internal.processors.cache;

import java.util.Collection;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cacheobject.IgniteCacheObjectProcessor;
import org.apache.ignite.internal.processors.query.QuerySchema;
import org.apache.ignite.internal.processors.query.QuerySchemaPatch;
import org.apache.ignite.internal.processors.query.schema.message.SchemaFinishDiscoveryMessage;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteUuid;
import org.jetbrains.annotations.Nullable;

/**
 * Cache start descriptor.
 */
public class DynamicCacheDescriptor {
    /** Cache start ID. */
    private IgniteUuid deploymentId;

    /** Cache configuration. */
    @GridToStringExclude
    private CacheConfiguration cacheCfg;

    /** Statically configured flag. */
    private final boolean staticCfg;

    /** SQL flag - whether the cache is created by an SQL command such as {@code CREATE TABLE}. */
    private boolean sql;

    /** Cache type. */
    private CacheType cacheType;

    /** Template configuration flag. */
    private boolean template;

    /** */
    private boolean updatesAllowed = true;

    /** */
    private Integer cacheId;

    /** */
    private final UUID rcvdFrom;

    /** Mutex. */
    private final Object mux = new Object();

    /** Cached object context for marshalling issues when cache isn't started. */
    private volatile CacheObjectContext objCtx;

    /** */
    private boolean rcvdOnDiscovery;

    /** */
    private AffinityTopologyVersion startTopVer;

    /** */
    private AffinityTopologyVersion rcvdFromVer;

    /** */
    private AffinityTopologyVersion clientCacheStartVer;

    /** Mutex to control schema. */
    private final Object schemaMux = new Object();

    /** Current schema. */
    private QuerySchema schema;

    /** */
    private final CacheGroupDescriptor grpDesc;

    /**
     * @param ctx Context.
     * @param cacheCfg Cache configuration.
     * @param cacheType Cache type.
     * @param grpDesc Group descriptor.
     * @param template {@code True} if this is template configuration.
     * @param rcvdFrom ID of node provided cache configuration
     * @param staticCfg {@code True} if cache statically configured.
     * @param sql SQL flag - whether the cache is created by an SQL command such as {@code CREATE TABLE}.
     * @param deploymentId Deployment ID.
     * @param schema Query schema.
     */
    @SuppressWarnings("unchecked")
    public DynamicCacheDescriptor(GridKernalContext ctx,
        CacheConfiguration cacheCfg,
        CacheType cacheType,
        CacheGroupDescriptor grpDesc,
        boolean template,
        UUID rcvdFrom,
        boolean staticCfg,
        boolean sql,
        IgniteUuid deploymentId,
        QuerySchema schema) {
        assert cacheCfg != null;
        assert grpDesc != null || template;
        assert schema != null;

        if (cacheCfg.getCacheMode() == CacheMode.REPLICATED && cacheCfg.getNearConfiguration() != null) {
            cacheCfg = new CacheConfiguration(cacheCfg);

            cacheCfg.setNearConfiguration(null);
        }

        this.cacheCfg = cacheCfg;
        this.cacheType = cacheType;
        this.grpDesc = grpDesc;
        this.template = template;
        this.rcvdFrom = rcvdFrom;
        this.staticCfg = staticCfg;
        this.sql = sql;
        this.deploymentId = deploymentId;

        cacheId = CU.cacheId(cacheCfg.getName());

        synchronized (schemaMux) {
            this.schema = schema.copy();
        }
    }

    /**
     * @return Cache group ID.
     */
    public int groupId() {
        assert grpDesc != null : this;

        return grpDesc.groupId();
    }

    /**
     * @return Cache group descriptor.
     */
    public CacheGroupDescriptor groupDescriptor() {
        assert grpDesc != null : this;

        return grpDesc;
    }

    /**
     * @return Cache ID.
     */
    public Integer cacheId() {
        return cacheId;
    }

    /**
     * @return {@code True} if this is template configuration.
     */
    public boolean template() {
        return template;
    }

    /**
     * @return Cache type.
     */
    public CacheType cacheType() {
        return cacheType;
    }

    /**
     * @return Start ID.
     */
    public IgniteUuid deploymentId() {
        return deploymentId;
    }

    /**
     * @return {@code True} if statically configured.
     */
    public boolean staticallyConfigured() {
        return staticCfg;
    }

    /**
     * @return SQL flag.
     */
    public boolean sql() {
        return sql;
    }

    /**
     * @return Cache name.
     */
    public String cacheName() {
        assert cacheCfg != null : this;

        return cacheCfg.getName();
    }

    /**
     * @return Cache configuration.
     */
    public CacheConfiguration cacheConfiguration() {
        return cacheCfg;
    }

    /**
     * Creates and caches cache object context if needed.
     *
     * @param proc Object processor.
     * @return Cache object context.
     * @throws IgniteCheckedException If failed.
     */
    public CacheObjectContext cacheObjectContext(IgniteCacheObjectProcessor proc) throws IgniteCheckedException {
        if (objCtx == null) {
            synchronized (mux) {
                if (objCtx == null)
                    objCtx = proc.contextForCache(cacheCfg);
            }
        }

        return objCtx;
    }

    /**
     * @return Updates allowed flag.
     */
    public boolean updatesAllowed() {
        return updatesAllowed;
    }

    /**
     * @param updatesAllowed Updates allowed flag.
     */
    public void updatesAllowed(boolean updatesAllowed) {
        this.updatesAllowed = updatesAllowed;
    }

    /**
     * @return {@code True} if received in discovery data.
     */
    boolean receivedOnDiscovery() {
        return rcvdOnDiscovery;
    }

    /**
     * @param rcvdOnDiscovery {@code True} if received in discovery data.
     */
    void receivedOnDiscovery(boolean rcvdOnDiscovery) {
        this.rcvdOnDiscovery = rcvdOnDiscovery;
    }

    /**
     * @return ID of node provided cache configuration in discovery data.
     */
    @Nullable public UUID receivedFrom() {
        return rcvdFrom;
    }

    /**
     * @return Topology version when node provided cache configuration was started.
     */
    @Nullable AffinityTopologyVersion receivedFromStartVersion() {
        return rcvdFromVer;
    }

    /**
     * @param rcvdFromVer Topology version when node provided cache configuration was started.
     */
    void receivedFromStartVersion(AffinityTopologyVersion rcvdFromVer) {
        this.rcvdFromVer = rcvdFromVer;
    }

    /**
     * @return Start topology version or {@code null} if cache configured statically.
     */
    @Nullable public AffinityTopologyVersion startTopologyVersion() {
        return startTopVer;
    }

    /**
     * @param startTopVer Start topology version.
     */
    public void startTopologyVersion(AffinityTopologyVersion startTopVer) {
        this.startTopVer = startTopVer;
    }

    /**
     * @return Version when client cache on local node was started.
     */
    @Nullable AffinityTopologyVersion clientCacheStartVersion() {
        return clientCacheStartVer;
    }

    /**
     * @param clientCacheStartVer Version when client cache on local node was started.
     */
    void clientCacheStartVersion(AffinityTopologyVersion clientCacheStartVer) {
        this.clientCacheStartVer = clientCacheStartVer;
    }

    /**
     * @return Schema.
     */
    public QuerySchema schema() {
        synchronized (schemaMux) {
            return schema.copy();
        }
    }

    /**
     * Set schema
     *
     * @param schema Schema.
     */
    public void schema(QuerySchema schema) {
        assert schema != null;

        synchronized (schemaMux) {
            this.schema = schema.copy();
        }
    }

    /**
     * Try applying finish message.
     *
     * @param msg Message.
     */
    public void schemaChangeFinish(SchemaFinishDiscoveryMessage msg) {
        synchronized (schemaMux) {
            schema.finish(msg);
        }
    }

    /**
     * Make schema patch for this cache.
     *
     * @param target Query entity list which current schema should be expanded to.
     * @return Patch which contains operations for expanding schema of this cache.
     * @see QuerySchemaPatch
     */
    public QuerySchemaPatch makeSchemaPatch(Collection<QueryEntity> target) {
        synchronized (schemaMux) {
            return schema.makePatch(target);
        }
    }

    /**
     * Apply query schema patch for changing current schema.
     *
     * @param patch patch to apply.
     * @return {@code true} if applying was success and {@code false} otherwise.
     */
    public boolean applySchemaPatch(QuerySchemaPatch patch) {
        synchronized (schemaMux) {
            return schema.applyPatch(patch);
        }
    }

    /**
     * Form a {@link StoredCacheData} with all data to correctly restore cache params when its configuration is read
     * from page store. Essentially, this method takes from {@link DynamicCacheDescriptor} all that's needed to start
     * cache correctly, leaving out everything else.
     */
    public StoredCacheData toStoredData() {
        assert schema != null;

        StoredCacheData res = new StoredCacheData(cacheConfiguration());

        res.queryEntities(schema().entities());
        res.sql(sql());

        return res;
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(DynamicCacheDescriptor.class, this, "cacheName", U.maskName(cacheCfg.getName()));
    }
}
