/*
 * 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.drill.exec.store.log;

import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.exec.physical.impl.scan.convert.StandardConversions;
import org.apache.drill.exec.physical.impl.scan.v3.ManagedReader;
import org.apache.drill.exec.physical.impl.scan.v3.file.FileDescrip;
import org.apache.drill.exec.physical.impl.scan.v3.file.FileSchemaNegotiator;
import org.apache.drill.exec.physical.resultSet.ResultSetLoader;
import org.apache.drill.exec.physical.resultSet.RowSetLoader;
import org.apache.drill.exec.record.metadata.ColumnMetadata;
import org.apache.drill.exec.record.metadata.TupleMetadata;
import org.apache.drill.exec.vector.accessor.ScalarWriter;
import org.apache.drill.exec.vector.accessor.TupleWriter;
import org.apache.drill.exec.vector.accessor.ValueWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LogBatchReader implements ManagedReader {
  private static final Logger logger = LoggerFactory.getLogger(LogBatchReader.class);
  public static final String RAW_LINE_COL_NAME = "_raw";
  public static final String UNMATCHED_LINE_COL_NAME = "_unmatched_rows";

  public static class LogReaderConfig {
    protected final LogFormatPlugin plugin;
    protected final Pattern pattern;
    protected final TupleMetadata providedSchema;
    protected final TupleMetadata tableSchema;
    protected final TupleMetadata readerSchema;
    protected final boolean asArray;
    protected final int groupCount;
    protected final int maxErrors;

    public LogReaderConfig(LogFormatPlugin plugin, Pattern pattern,
        TupleMetadata providedSchema, TupleMetadata tableSchema,
        TupleMetadata readerSchema,
        boolean asArray, int groupCount, int maxErrors) {
      this.plugin = plugin;
      this.pattern = pattern;
      this.providedSchema = providedSchema;
      this.tableSchema = tableSchema;
      this.readerSchema = readerSchema;
      this.asArray = asArray;
      this.groupCount = groupCount;
      this.maxErrors = maxErrors;
    }
  }

  /**
   * Write group values to value vectors.
   */
  private interface VectorWriter {
    void loadVectors(Matcher m);
  }

  /**
   * Write group values to individual scalar columns.
   */
  private static class ScalarGroupWriter implements VectorWriter {

    private final ValueWriter[] writers;

    public ScalarGroupWriter(TupleWriter rowWriter,
        TupleMetadata readerSchema, StandardConversions conversions) {
      writers = new ValueWriter[readerSchema.size()];
      for (int i = 0; i < writers.length; i++) {
        ColumnMetadata colSchema = readerSchema.metadata(i);
        writers[i] = conversions.converterFor(rowWriter.scalar(i), colSchema);
      }
    }

    @Override
    public void loadVectors(Matcher m) {
      for (int i = 0; i < m.groupCount(); i++) {
        String value = m.group(i + 1);
        if (value != null) {
          writers[i].setString(value);
        }
      }
    }
  }

  /**
   * Write group values to the columns[] array.
   */
  private static class ColumnsArrayWriter implements VectorWriter {

    private final ScalarWriter elementWriter;

    public ColumnsArrayWriter(TupleWriter rowWriter) {
      elementWriter = rowWriter.array(0).scalar();
    }

   @Override
    public void loadVectors(Matcher m) {
      for (int i = 0; i < m.groupCount(); i++) {
        String value = m.group(i + 1);
        elementWriter.setString(value == null ? "" : value);
      }
    }
  }

  private final LogReaderConfig config;
  private final FileDescrip file;
  private BufferedReader reader;
  private ResultSetLoader loader;
  private VectorWriter vectorWriter;
  private ScalarWriter rawColWriter;
  private ScalarWriter unmatchedColWriter;
  private boolean saveMatchedRows;
  private int lineNumber;
  private int errorCount;

  public LogBatchReader(LogReaderConfig config, FileSchemaNegotiator negotiator) {
    this.config = config;
    this.file = negotiator.file();
    negotiator.tableSchema(config.tableSchema, true);
    loader = negotiator.build();
    bindColumns(loader.writer());
    openFile();
  }

  private void bindColumns(RowSetLoader writer) {
    rawColWriter = writer.scalar(RAW_LINE_COL_NAME);
    unmatchedColWriter = writer.scalar(UNMATCHED_LINE_COL_NAME);
    saveMatchedRows = rawColWriter.isProjected();

    // If no match-case columns are projected, and the unmatched
    // columns is unprojected, then we want to count (matched)
    // rows.
    saveMatchedRows |= !unmatchedColWriter.isProjected();

    // This reader is unusual: it can save only unmatched rows,
    // save only matched rows, or both. We check if we want to
    // save matched rows to by checking if any of the "normal"
    // reader columns are projected (ignoring the two special
    // columns.) If so, create a vector writer to save values.
    if (config.asArray) {
      saveMatchedRows |= writer.column(0).isProjected();
      if (saveMatchedRows) {
         // Save columns as an array
        vectorWriter = new ColumnsArrayWriter(writer);
      }
    } else {
      for (int i = 0; i <  config.readerSchema.size(); i++) {
        saveMatchedRows |= writer.column(i).isProjected();
      }
      if (saveMatchedRows) {
        // Save using the defined columns
        TupleMetadata providedSchema = config.providedSchema;
        StandardConversions conversions = StandardConversions.builder()
            .withSchema(providedSchema)
            .build();
        vectorWriter = new ScalarGroupWriter(writer, config.readerSchema, conversions);
      }
    }
  }

  private void openFile() {
    InputStream in;
    try {
      in = file.fileSystem().openPossiblyCompressedStream(file.split().getPath());
    } catch (Exception e) {
      throw UserException
          .dataReadError(e)
          .message("Failed to open input file")
          .addContext(String.format("File path: %s", file.split().getPath()))
          .addContext(loader.errorContext())
          .build(logger);
    }
    reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
  }

  @Override
  public boolean next() {
    RowSetLoader rowWriter = loader.writer();
    while (! rowWriter.isFull()) {
      if (! nextLine(rowWriter)) {
        return false;
      }
    }
    return true;
  }

  private boolean nextLine(RowSetLoader rowWriter) {
    String line;
    try {
      line = reader.readLine();
    } catch (IOException e) {
      throw UserException
          .dataReadError(e)
          .message("Error reading file")
          .addContext(String.format("File: %s", file.split().getPath()))
          .addContext(loader.errorContext())
          .build(logger);
    }

    if (line == null) {
      return false;
    }
    lineNumber++;
    Matcher lineMatcher = config.pattern.matcher(line);
    if (lineMatcher.matches()) {

      // Load matched row into vectors.
      if (saveMatchedRows) {
        rowWriter.start();
        rawColWriter.setString(line);
        vectorWriter.loadVectors(lineMatcher);
        rowWriter.save();
      }
      return true;
    }

    errorCount++;
    if (errorCount < config.maxErrors) {
      logger.warn("Unmatched line: {}", line);
    } else {
      throw UserException.parseError()
          .message("Too many errors. Max error threshold exceeded.")
          .addContext("Line", line)
          .addContext("Line number", lineNumber)
          .addContext(loader.errorContext())
          .build(logger);
    }

    // For unmatched columns, create an output row only if the
    // user asked for the unmatched values.
    if (unmatchedColWriter.isProjected()) {
      rowWriter.start();
      unmatchedColWriter.setString(line);
      rowWriter.save();
    }
    return true;
  }

  @Override
  public void close() {
    if (reader == null) {
      return;
    }
    try {
      reader.close();
    } catch (IOException e) {
      logger.warn("Error when closing file: " + file.split().getPath(), e);
    } finally {
      reader = null;
    }
  }

  @Override
  public String toString() {
    return String.format(
        "LogRecordReader[File=%s, Line=%d]",
        file.split().getPath(), lineNumber);
  }
}
