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

import org.apache.ignite.Ignite;
import org.apache.ignite.cache.QueryIndexType;
import org.apache.ignite.internal.GridKernalContext;
import org.apache.ignite.internal.IgniteKernal;
import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
import org.apache.ignite.internal.processors.datastructures.DataStructuresProcessor;
import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor;
import org.apache.ignite.internal.processors.task.GridInternal;
import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteCallable;
import org.apache.ignite.resources.IgniteInstanceResource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;

/**
 * Metadata job.
 */
@GridInternal
class GridCacheQuerySqlMetadataJobV2 implements IgniteCallable<Collection<GridCacheQueryManager.CacheSqlMetadata>> {
    /** */
    private static final long serialVersionUID = 0L;

    /** Number of fields to report when no fields defined. Includes _key and _val columns. */
    private static final int NO_FIELDS_COLUMNS_COUNT = 2;

    /** Grid */
    @IgniteInstanceResource
    private Ignite ignite;

    /** {@inheritDoc} */
    @Override public Collection<GridCacheQueryManager.CacheSqlMetadata> call() {
        final GridKernalContext ctx = ((IgniteKernal)ignite).context();

        Collection<String> cacheNames = F.viewReadOnly(ctx.cache().caches(),
            new C1<IgniteInternalCache<?, ?>, String>() {
                @Override public String apply(IgniteInternalCache<?, ?> c) {
                    return c.name();
                }
            },
            new P1<IgniteInternalCache<?, ?>>() {
                @Override public boolean apply(IgniteInternalCache<?, ?> c) {
                    return !CU.isSystemCache(c.name()) && !DataStructuresProcessor.isDataStructureCache(c.name());
                }
            }
        );

        return F.transform(cacheNames, new C1<String, GridCacheQueryManager.CacheSqlMetadata>() {
            @Override public GridCacheQueryManager.CacheSqlMetadata apply(String cacheName) {
                Collection<GridQueryTypeDescriptor> types = ctx.query().types(cacheName);

                Collection<String> names = U.newHashSet(types.size());
                Map<String, String> keyClasses = U.newHashMap(types.size());
                Map<String, String> valClasses = U.newHashMap(types.size());
                Map<String, Map<String, String>> fields = U.newHashMap(types.size());
                Map<String, Collection<GridCacheSqlIndexMetadata>> indexes = U.newHashMap(types.size());
                Map<String, Set<String>> notNullFields = U.newHashMap(types.size());

                for (GridQueryTypeDescriptor type : types) {
                    // Filter internal types (e.g., data structures).
                    if (type.name().startsWith("GridCache"))
                        continue;

                    names.add(type.name());

                    keyClasses.put(type.name(), type.keyClass().getName());
                    valClasses.put(type.name(), type.valueClass().getName());

                    int size = type.fields().isEmpty() ? NO_FIELDS_COLUMNS_COUNT : type.fields().size();

                    Map<String, String> fieldsMap = U.newLinkedHashMap(size);
                    HashSet<String> notNullFieldsSet = U.newHashSet(1);

                    // _KEY and _VAL are not included in GridIndexingTypeDescriptor.valueFields
                    if (type.fields().isEmpty()) {
                        fieldsMap.put("_KEY", type.keyClass().getName());
                        fieldsMap.put("_VAL", type.valueClass().getName());
                    }

                    for (Map.Entry<String, Class<?>> e : type.fields().entrySet()) {
                        String fieldName = e.getKey();

                        fieldsMap.put(fieldName.toUpperCase(), e.getValue().getName());

                        if (type.property(fieldName).notNull())
                            notNullFieldsSet.add(fieldName.toUpperCase());
                    }

                    fields.put(type.name(), fieldsMap);
                    notNullFields.put(type.name(), notNullFieldsSet);

                    Map<String, GridQueryIndexDescriptor> idxs = type.indexes();

                    Collection<GridCacheSqlIndexMetadata> indexesCol = new ArrayList<>(idxs.size());

                    for (Map.Entry<String, GridQueryIndexDescriptor> e : idxs.entrySet()) {
                        GridQueryIndexDescriptor desc = e.getValue();

                        // Add only SQL indexes.
                        if (desc.type() == QueryIndexType.SORTED) {
                            Collection<String> idxFields = new LinkedList<>();
                            Collection<String> descendings = new LinkedList<>();

                            for (String idxField : e.getValue().fields()) {
                                String idxFieldUpper = idxField.toUpperCase();

                                idxFields.add(idxFieldUpper);

                                if (desc.descending(idxField))
                                    descendings.add(idxFieldUpper);
                            }

                            indexesCol.add(new GridCacheQueryManager.CacheSqlIndexMetadata(e.getKey().toUpperCase(),
                                idxFields, descendings, false));
                        }
                    }

                    indexes.put(type.name(), indexesCol);
                }

                return new GridCacheQuerySqlMetadataV2(cacheName, names, keyClasses, valClasses, fields, indexes,
                    notNullFields);
            }
        });
    }
}
