/*
 * 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.carbondata.core.scan.filter.resolver.resolverinfo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.carbondata.core.metadata.datatype.DataTypes;
import org.apache.carbondata.core.metadata.schema.table.column.CarbonColumn;
import org.apache.carbondata.core.metadata.schema.table.column.CarbonDimension;
import org.apache.carbondata.core.metadata.schema.table.column.CarbonMeasure;
import org.apache.carbondata.core.scan.expression.exception.FilterUnsupportedException;
import org.apache.carbondata.core.scan.filter.ColumnFilterInfo;
import org.apache.carbondata.core.scan.filter.resolver.metadata.FilterResolverMetadata;
import org.apache.carbondata.core.scan.filter.resolver.resolverinfo.visitor.ResolvedFilterInfoVisitorIntf;

public class MeasureColumnResolvedFilterInfo extends ColumnResolvedFilterInfo
    implements Serializable {
  /**
   *
   */
  private static final long serialVersionUID = 4222568289115151561L;

  private int rowIndex = -1;

  private boolean isMeasureExistsInCurrentSlice = true;

  private CarbonColumn carbonColumn;

  private CarbonMeasure carbonMeasure;

  /**
   * resolved filter object of a particular filter Expression.
   */
  private ColumnFilterInfo resolvedFilterValueObj;

  private Map<CarbonMeasure, List<ColumnFilterInfo>> measureResolvedFilter;

  private org.apache.carbondata.core.metadata.datatype.DataType type;

  public int getColumnIndex() {
    return columnIndex;
  }

  public MeasureColumnResolvedFilterInfo() {
    measureResolvedFilter = new HashMap<CarbonMeasure, List<ColumnFilterInfo>>(20);
  }

  public void addMeasureResolvedFilterInstance(CarbonMeasure measures,
      ColumnFilterInfo filterResolvedObj) {
    List<ColumnFilterInfo> currentValues = measureResolvedFilter.get(measures);
    if (null == currentValues) {
      currentValues = new ArrayList<ColumnFilterInfo>(20);
      currentValues.add(filterResolvedObj);
      measureResolvedFilter.put(measures, currentValues);
    } else {
      currentValues.add(filterResolvedObj);
    }
  }

  public ColumnFilterInfo getFilterValues() {
    return resolvedFilterValueObj;
  }

  public void setFilterValues(final ColumnFilterInfo resolvedFilterValueObj) {
    this.resolvedFilterValueObj = resolvedFilterValueObj;
  }

  public void setColumnIndex(int columnIndex) {
    this.columnIndex = columnIndex;
  }

  public int getRowIndex() {
    return rowIndex;
  }

  public void setRowIndex(int rowIndex) {
    this.rowIndex = rowIndex;
  }

  public org.apache.carbondata.core.metadata.datatype.DataType getType() {
    return type;
  }

  public void setType(org.apache.carbondata.core.metadata.datatype.DataType dataType) {
    this.type = DataTypes.valueOf(dataType.getId());
  }

  public CarbonColumn getCarbonColumn() {
    return carbonColumn;
  }

  public void setCarbonColumn(CarbonColumn carbonColumn) {
    this.carbonColumn = carbonColumn;
  }

  public CarbonMeasure getMeasure() {
    return carbonMeasure;
  }

  @Override
  public CarbonDimension getDimension() {
    throw new UnsupportedOperationException("Operation not supported");
  }

  public void setMeasureExistsInCurrentSlice(boolean measureExistsInCurrentSlice) {
    isMeasureExistsInCurrentSlice = measureExistsInCurrentSlice;
  }

  public void setMeasure(CarbonMeasure carbonMeasure) {
    this.carbonMeasure = carbonMeasure;
  }

  public void populateFilterInfoBasedOnColumnType(ResolvedFilterInfoVisitorIntf visitor,
      FilterResolverMetadata metadata) throws FilterUnsupportedException {
    if (null != visitor) {
      visitor.populateFilterResolvedInfo(this, metadata);
      this.addMeasureResolvedFilterInstance(metadata.getColumnExpression().getMeasure(),
          this.getFilterValues());
      this.setMeasure(metadata.getColumnExpression().getMeasure());
      this.setColumnIndex(metadata.getColumnExpression().getMeasure().getOrdinal());
    }
  }

  /**
   * This method will clone the current object
   *
   * @return
   */
  public MeasureColumnResolvedFilterInfo getCopyObject() {
    MeasureColumnResolvedFilterInfo msrColumnResolvedFilterInfo =
        new MeasureColumnResolvedFilterInfo();
    msrColumnResolvedFilterInfo.resolvedFilterValueObj = this.resolvedFilterValueObj;
    msrColumnResolvedFilterInfo.rowIndex = this.rowIndex;
    msrColumnResolvedFilterInfo.measureResolvedFilter = this.measureResolvedFilter;
    msrColumnResolvedFilterInfo.setMeasureExistsInCurrentSlice(this.isMeasureExistsInCurrentSlice);
    msrColumnResolvedFilterInfo.columnIndexInMinMaxByteArray = columnIndexInMinMaxByteArray;
    return msrColumnResolvedFilterInfo;
  }

}
