/*
 * 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.mock;

import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Table;
import org.apache.drill.common.JSONOptions;
import org.apache.drill.common.expression.SchemaPath;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.common.util.JacksonUtils;
import org.apache.drill.exec.physical.base.AbstractGroupScan;
import org.apache.drill.exec.planner.logical.DynamicDrillTable;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.store.AbstractSchema;
import org.apache.drill.exec.store.AbstractStoragePlugin;
import org.apache.drill.exec.store.SchemaConfig;
import org.apache.drill.exec.store.mock.MockTableDef.MockScanEntry;
import org.apache.drill.exec.store.mock.MockTableDef.MockTableSelection;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;

public class MockStorageEngine extends AbstractStoragePlugin {

  private final MockStorageEngineConfig configuration;
  private final MockSchema schema;

  public MockStorageEngine(MockStorageEngineConfig configuration, DrillbitContext context, String name) {
    super(context, name);
    this.configuration = configuration;
    this.schema = new MockSchema(this, name);
  }

  @Override
  public AbstractGroupScan getPhysicalScan(String userName, JSONOptions selection, List<SchemaPath> columns)
      throws IOException {

    MockTableSelection tableSelection = selection.getWith(
      JacksonUtils.createObjectMapper(),
      MockTableSelection.class
    );
    List<MockScanEntry> readEntries = tableSelection.getEntries();
    assert ! readEntries.isEmpty();
    return new MockGroupScanPOP(null, readEntries);
  }

  @Override
  public void registerSchemas(SchemaConfig schemaConfig, SchemaPlus parent) throws IOException {
    parent.add(schema.getName(), schema);
  }

  @Override
  public StoragePluginConfig getConfig() {
    return configuration;
  }

  @Override
  public boolean supportsRead() {
    return true;
  }

  /**
   * Resolves table names within the mock data source. Tables can be of two forms:
   * <p>
   * <tt><name>_<n><unit></tt>
   * <p>
   * Where the "name" can be anything, "n" is the number of rows, and "unit" is
   * the units for the row count: non, K (thousand) or M (million).
   * <p>
   * The above form generates a table directly with no other information needed.
   * Column names must be provided, and must be of the form:
   * <p>
   * <tt><name>_<type><size></tt>
   * <p>
   * Where the name can be anything, the type must be i (integer), d (double),
   * b (boolean)
   * or s (string, AKA VarChar). The length is needed only for string fields.
   * <p>
   * Direct tables are quick, but limited. The other option is to provide the
   * name of a definition file:
   * <p>
   * <tt><fileName>.json</tt>
   * <p>
   * In this case, the JSON file must be a resource visible on the class path.
   * Omit the leading slash in the resource path name.
   */

  private static class MockSchema extends AbstractSchema {

    private final MockStorageEngine engine;
    private final Map<String, Table> tableCache = new WeakHashMap<>();

    public MockSchema(MockStorageEngine engine) {
      super(ImmutableList.<String>of(), MockStorageEngineConfig.NAME);
      this.engine = engine;
    }

    public MockSchema(MockStorageEngine engine, String name) {
      super(ImmutableList.<String>of(), name);
      this.engine = engine;
    }

    @Override
    public Table getTable(String name) {
      Table table = tableCache.get(name);
      if (table == null) {
        if (name.toLowerCase().endsWith(".json")) {
          table = getConfigFile(name);
        } else {
          table = getDirectTable(name);
        }
        tableCache.put(name, table);
      }
      return table;
    }

    private Table getConfigFile(String name) {
      final URL url = Resources.getResource(name);
      if (url == null) {
        throw new IllegalArgumentException(
            "Unable to find mock table config file " + name);
      }
      MockTableDef mockTableDefn;
      try {
        String json = Resources.toString(url, StandardCharsets.UTF_8);
        final ObjectMapper mapper = JacksonUtils.createObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mockTableDefn = mapper.readValue(json, MockTableDef.class);
      } catch (JsonParseException e) {
        throw new IllegalArgumentException("Unable to parse mock table definition file: " + name, e);
      } catch (JsonMappingException e) {
        throw new IllegalArgumentException("Unable to Jackson deserialize mock table definition file: " + name, e);
      } catch (IOException e) {
        throw new IllegalArgumentException("Unable to read mock table definition file: " + name, e);
      }

      return new DynamicDrillTable(engine, this.name, mockTableDefn.getEntries());
    }

    private Table getDirectTable(String name) {
      Pattern p = Pattern.compile("(\\w+)_(\\d+)(k|m)?", Pattern.CASE_INSENSITIVE);
      Matcher m = p.matcher(name);
      if (! m.matches()) {
        return null;
      }
      @SuppressWarnings("unused")
      String baseName = m.group(1);
      int n = Integer.parseInt(m.group(2));
      String unit = m.group(3);
      if (unit == null) { }
      else if (unit.equalsIgnoreCase("K")) { n *= 1000; }
      else if (unit.equalsIgnoreCase("M")) { n *= 1_000_000; }
      MockScanEntry entry = new MockTableDef.MockScanEntry(n, true, 0, 1, null);
      MockTableSelection entries = new MockTableSelection(ImmutableList.<MockScanEntry>of(entry));
      return new DynamicDrillTable(engine, this.name, entries);
    }

    @Override
    public Set<String> getTableNames() {
      return new HashSet<>();
    }

    @Override
    public String getTypeName() {
      return MockStorageEngineConfig.NAME;
    }
  }
}
