package com.lanyuanxiaoyao.service.command.utils;

import com.lanyuanxiaoyao.service.common.entity.TableMeta;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.shell.table.TableModelBuilder;

/**
 * 表相关工具
 *
 * @author ZhangJiacheng
 * @date 2022-05-23
 */
public class TableUtils {
    public static String makeTableMeta(TableMeta meta) {
        TableModelBuilder<Object> tableMetaModelBuilder = new TableModelBuilder<>();
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Alias");
        tableMetaModelBuilder.addValue(meta.getAlias());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Source database");
        tableMetaModelBuilder.addValue(meta.getSource());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Source Type");
        tableMetaModelBuilder.addValue(meta.getSourceType());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Source schema");
        tableMetaModelBuilder.addValue(meta.getSchema());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Source table");
        tableMetaModelBuilder.addValue(meta.getTable());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Table type");
        tableMetaModelBuilder.addValue(meta.getType());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Primary keys");
        tableMetaModelBuilder.addValue(meta.getPrimaryKeys().stream().map(TableMeta.FieldMeta::getName).collect(Collectors.joining(",")));
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Partition keys");
        tableMetaModelBuilder.addValue(meta.getPartitionKeys().stream().map(TableMeta.FieldMeta::getName).collect(Collectors.joining(",")));
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Hudi partition field");
        tableMetaModelBuilder.addValue(meta.getPartitionField());
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Tags");
        tableMetaModelBuilder.addValue(String.join(", ", meta.getTags()));
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Fields");
        TableModelBuilder<Object> fieldsModelBuilder = new TableModelBuilder<>();
        fieldsModelBuilder.addRow();
        fieldsModelBuilder.addValue("#");
        fieldsModelBuilder.addValue("Name");
        fieldsModelBuilder.addValue("Type");
        fieldsModelBuilder.addValue("Length");
        fieldsModelBuilder.addValue("Primary key");
        fieldsModelBuilder.addValue("Partition key");
        List<TableMeta.FieldMeta> fields = meta.getFields()
                .stream()
                .sorted(Comparator.comparingInt(TableMeta.FieldMeta::getSequence))
                .collect(Collectors.toList());
        for (TableMeta.FieldMeta field : fields) {
            fieldsModelBuilder.addRow();
            fieldsModelBuilder.addValue(field.getSequence());
            fieldsModelBuilder.addValue(field.getName());
            fieldsModelBuilder.addValue(field.getType());
            fieldsModelBuilder.addValue(field.getLength());
            fieldsModelBuilder.addValue(field.getPrimaryKey() ? ShellTableUtils.CHECK_TRUE : "");
            fieldsModelBuilder.addValue(field.getPartitionKey() ? ShellTableUtils.CHECK_TRUE : "");
        }
        tableMetaModelBuilder.addValue(ShellTableUtils.renderInnerTable(fieldsModelBuilder));
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Hudi config");
        TableModelBuilder<Object> hudiModelBuilder = new TableModelBuilder<>();
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Write parallelism");
        hudiModelBuilder.addValue(meta.getHudi().getWriteTasks());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Write task memory");
        hudiModelBuilder.addValue(meta.getHudi().getWriteTaskMaxMemory());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Write batch size");
        hudiModelBuilder.addValue(meta.getHudi().getWriteBatchSize());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Write rate limit");
        hudiModelBuilder.addValue(meta.getHudi().getWriteRateLimit());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Bucket number");
        hudiModelBuilder.addValue(meta.getHudi().getBucketIndexNumber());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Compaction parallelism");
        hudiModelBuilder.addValue(meta.getHudi().getCompactionTasks());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Compaction strategy");
        hudiModelBuilder.addValue(meta.getHudi().getCompactionStrategy());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Compaction delta commits");
        hudiModelBuilder.addValue(meta.getHudi().getCompactionDeltaCommits());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Compaction delta seconds");
        hudiModelBuilder.addValue(meta.getHudi().getCompactionDeltaSeconds());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Keep file version number");
        hudiModelBuilder.addValue(meta.getHudi().getKeepFileVersion());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Keep commit version number");
        hudiModelBuilder.addValue(meta.getHudi().getKeepCommitVersion());
        hudiModelBuilder.addRow();
        hudiModelBuilder.addValue("Target HDFS path");
        hudiModelBuilder.addValue(meta.getHudi().getTargetHdfsPath());
        tableMetaModelBuilder.addValue(ShellTableUtils.renderInnerTable(hudiModelBuilder));
        Function<TableMeta.YarnMeta, TableModelBuilder<Object>> generateYarnJob = yarnMeta -> {
            TableModelBuilder<Object> builder = new TableModelBuilder<>();
            builder.addRow();
            builder.addValue("Job manager memory");
            builder.addValue(yarnMeta.getJobManagerMemory());
            builder.addRow();
            builder.addValue("Task manager memory");
            builder.addValue(yarnMeta.getTaskManagerMemory());
            return builder;
        };
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Sync yarn");
        tableMetaModelBuilder.addValue(ShellTableUtils.renderInnerTable(generateYarnJob.apply(meta.getSyncYarn())));
        tableMetaModelBuilder.addRow();
        tableMetaModelBuilder.addValue("Compaction yarn");
        tableMetaModelBuilder.addValue(ShellTableUtils.renderInnerTable(generateYarnJob.apply(meta.getCompactionYarn())));

        return ShellTableUtils.renderTable(tableMetaModelBuilder);
    }
}
