/*
 *
 * 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.cassandra.cql3.selection;

import java.util.*;
import java.util.stream.Collectors;

import com.google.common.base.Objects;
import com.google.common.collect.*;

import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.cql3.ColumnSpecification;

/**
 * Separately maintains the ColumnSpecifications and their mappings to underlying
 * columns as we may receive null mappings. This occurs where a query result
 * includes a column specification which does not map to any particular real
 * column, e.g. COUNT queries or where no-arg functions like now() are used
 */
public class SelectionColumnMapping implements SelectionColumns
{
    private final ArrayList<ColumnSpecification> columnSpecifications;
    private final HashMultimap<ColumnSpecification, ColumnDefinition> columnMappings;

    private SelectionColumnMapping()
    {
        this.columnSpecifications = new ArrayList<>();
        this.columnMappings = HashMultimap.create();
    }

    protected static SelectionColumnMapping newMapping()
    {
        return new SelectionColumnMapping();
    }

    protected static SelectionColumnMapping simpleMapping(Iterable<ColumnDefinition> columnDefinitions)
    {
        SelectionColumnMapping mapping = new SelectionColumnMapping();
        for (ColumnDefinition def: columnDefinitions)
            mapping.addMapping(def, def);
        return mapping;
    }

    protected SelectionColumnMapping addMapping(ColumnSpecification colSpec, ColumnDefinition column)
    {
        columnSpecifications.add(colSpec);
        // functions without arguments do not map to any column, so don't
        // record any mapping in that case
        if (column != null)
            columnMappings.put(colSpec, column);
        return this;
    }

    protected SelectionColumnMapping addMapping(ColumnSpecification colSpec, Iterable<ColumnDefinition> columns)
    {
        columnSpecifications.add(colSpec);
        columnMappings.putAll(colSpec, columns);
        return this;
    }

    public List<ColumnSpecification> getColumnSpecifications()
    {
        // return a mutable copy as we may add extra columns
        // for ordering (CASSANDRA-4911 & CASSANDRA-8286)
        return Lists.newArrayList(columnSpecifications);
    }

    public Multimap<ColumnSpecification, ColumnDefinition> getMappings()
    {
        return Multimaps.unmodifiableMultimap(columnMappings);
    }

    public boolean equals(Object obj)
    {
        if (obj == null)
            return false;

        if (!(obj instanceof SelectionColumnMapping))
            return false;

        SelectionColumns other = (SelectionColumns)obj;
        return Objects.equal(columnMappings, other.getMappings())
            && Objects.equal(columnSpecifications, other.getColumnSpecifications());
    }

    public int hashCode()
    {
        return Objects.hashCode(columnMappings);
    }

    public String toString()
    {
        return columnMappings.asMap()
                             .entrySet()
                             .stream()
                             .map(entry ->
                                  entry.getValue()
                                       .stream()
                                       .map(colDef -> colDef.name.toString())
                                       .collect(Collectors.joining(", ", entry.getKey().name.toString() + ":[", "]")))
                             .collect(Collectors.joining(", ",
                                                         columnSpecifications.stream()
                                                                             .map(colSpec -> colSpec.name.toString())
                                                                             .collect(Collectors.joining(", ",
                                                                                                         "{ Columns:[",
                                                                                                         "], Mappings:{")),
                                                         "} }"));
    }
}
