/*
 * Licensed to Crate under one or more contributor license agreements.
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.  Crate 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.
 *
 * However, if you have executed another commercial license agreement
 * with Crate these terms will supersede the license and you may use the
 * software solely pursuant to the terms of the relevant commercial
 * agreement.
 */

package io.crate.metadata.information;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedMap;
import io.crate.metadata.ColumnIdent;
import io.crate.metadata.IngestionRuleInfo;
import io.crate.metadata.Reference;
import io.crate.metadata.ReferenceIdent;
import io.crate.metadata.RelationName;
import io.crate.metadata.RowContextCollectorExpression;
import io.crate.metadata.RowGranularity;
import io.crate.metadata.expressions.RowCollectExpressionFactory;
import io.crate.types.DataType;
import io.crate.types.DataTypes;

import java.util.Map;


public class InformationSchemaIngestionRulesTableInfo extends InformationTableInfo {

    public static final String NAME = "ingestion_rules";
    public static final RelationName IDENT = new RelationName(InformationSchemaInfo.NAME, NAME);

    public static class Columns {
        static final ColumnIdent RULE_NAME = new ColumnIdent("rule_name");
        static final ColumnIdent SOURCE_IDENT = new ColumnIdent("source_ident");
        static final ColumnIdent TARGET_TABLE = new ColumnIdent("target_table");
        static final ColumnIdent CONDITION = new ColumnIdent("condition");
    }

    public static class References {
        static final Reference RULE_NAME = info(Columns.RULE_NAME, DataTypes.STRING);
        static final Reference SOURCE_IDENT = info(Columns.SOURCE_IDENT, DataTypes.STRING);
        static final Reference TARGET_TABLE = info(Columns.TARGET_TABLE, DataTypes.STRING);
        static final Reference CONDITION = info(Columns.CONDITION, DataTypes.STRING);
    }

    private static final ImmutableList<ColumnIdent> PRIMARY_KEY = ImmutableList.of(
        Columns.RULE_NAME);

    public static Map<ColumnIdent, RowCollectExpressionFactory<IngestionRuleInfo>> expressions() {
        return ImmutableMap.<ColumnIdent, RowCollectExpressionFactory<IngestionRuleInfo>>builder()
            .put(Columns.RULE_NAME,
                () -> RowContextCollectorExpression.objToBytesRef(IngestionRuleInfo::getName))
            .put(Columns.SOURCE_IDENT,
                () -> RowContextCollectorExpression.objToBytesRef(IngestionRuleInfo::getSource))
            .put(Columns.TARGET_TABLE,
                () -> RowContextCollectorExpression.objToBytesRef(IngestionRuleInfo::getTarget))
            .put(Columns.CONDITION,
                () -> RowContextCollectorExpression.objToBytesRef(IngestionRuleInfo::getCondition))
            .build();
    }

    private static Reference info(ColumnIdent columnIdent, DataType dataType) {
        return new Reference(new ReferenceIdent(IDENT, columnIdent), RowGranularity.DOC, dataType);
    }

    InformationSchemaIngestionRulesTableInfo() {
        super(
            IDENT,
            PRIMARY_KEY,
            ImmutableSortedMap.<ColumnIdent, Reference>naturalOrder()
                .put(Columns.RULE_NAME, References.RULE_NAME)
                .put(Columns.SOURCE_IDENT, References.SOURCE_IDENT)
                .put(Columns.TARGET_TABLE, References.TARGET_TABLE)
                .put(Columns.CONDITION, References.CONDITION)
                .build()
        );
    }
}

@@ -1131,61 +1131,8 @@
 ap;%0A
-import com.google.common.collect.ImmutableSortedMap;%0A
 impo
@@ -1213,85 +1213,8 @@
 fo;%0A
-import io.crate.metadata.Reference;%0Aimport io.crate.metadata.ReferenceIdent;%0A
 impo
@@ -1427,30 +1427,46 @@
 o.crate.
-types.DataType
+metadata.table.ColumnRegistrar
 ;%0Aimport
@@ -2112,37 +2112,38 @@
     %7D%0A%0A    p
-ublic
+rivate
  static 
 class Refere
@@ -2134,74 +2134,127 @@
 tic 
-class References %7B%0A        static final Reference RULE_NAME = info
+ColumnRegistrar columnRegistrar() %7B%0A        return new ColumnRegistrar(IDENT, RowGranularity.DOC)%0A            .register
 (Col
@@ -2278,33 +2278,32 @@
 ataTypes.STRING)
-;
 %0A        static 
@@ -2299,50 +2299,21 @@
     
-static final Reference SOURCE_IDENT = info
+    .register
 (Col
@@ -2340,33 +2340,32 @@
 ataTypes.STRING)
-;
 %0A        static 
@@ -2361,50 +2361,21 @@
     
-static final Reference TARGET_TABLE = info
+    .register
 (Col
@@ -2406,25 +2406,24 @@
 ypes.STRING)
-;
 %0A        sta
@@ -2423,47 +2423,21 @@
     
-static final Reference CONDITION = info
+    .register
 (Col
@@ -2482,121 +2482,8 @@
  %7D%0A%0A
-    private static final ImmutableList%3CColumnIdent%3E PRIMARY_KEY = ImmutableList.of(%0A        Columns.RULE_NAME);%0A%0A
     
@@ -3248,195 +3248,8 @@
  %7D%0A%0A
-    private static Reference info(ColumnIdent columnIdent, DataType dataType) %7B%0A        return new Reference(new ReferenceIdent(IDENT, columnIdent), RowGranularity.DOC, dataType);%0A    %7D%0A%0A
     
@@ -3343,90 +3343,26 @@
     
-PRIMARY_KEY,%0A            ImmutableSortedMap.%3CColumnIdent, Reference%3EnaturalOrde
+columnRegistra
 r()
+,
 %0A   
@@ -3374,279 +3374,42 @@
     
-    .put(Columns.RULE_NAME, References.RULE_NAME)%0A                .put(Columns.SOURCE_IDENT, References.SOURCE_IDENT)%0A                .put(Columns.TARGET_TABLE, References.TARGET_TABLE)%0A                .put(Columns.CONDITION, References.CONDITION)%0A                .build(
+ImmutableList.of(Columns.RULE_NAME
 )%0A  

use ColumnRegistrar in InformationIngestionRulesTableInfo