package co.cask.mmds.manager;


import co.cask.cdap.api.ServiceDiscoverer;
import co.cask.cdap.api.data.schema.Schema;
import co.cask.cdap.api.metadata.Metadata;
import co.cask.cdap.api.metadata.MetadataEntity;
import co.cask.cdap.api.metadata.MetadataScope;
import co.cask.cdap.api.plugin.PluginContext;
import co.cask.cdap.api.plugin.PluginProperties;
import co.cask.cdap.etl.api.Arguments;
import co.cask.cdap.etl.api.Lookup;
import co.cask.cdap.etl.api.StageMetrics;
import co.cask.cdap.etl.api.TransformContext;
import co.cask.cdap.etl.api.lineage.field.Operation;

import java.net.URL;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

// TODO: remove usage of Hydrator classes. Requires wrangler work

/**
 * Implements TransformContext required by the WranglerTransform.
 */
public class WranglerContext implements TransformContext {
  private final PluginContext pluginContext;
  private final ServiceDiscoverer serviceDiscoverer;

  public WranglerContext(PluginContext pluginContext, ServiceDiscoverer serviceDiscoverer) {
    this.pluginContext = pluginContext;
    this.serviceDiscoverer = serviceDiscoverer;
  }

  @Override
  public <T> Lookup<T> provide(String s, Map<String, String> map) {
    throw new UnsupportedOperationException("Lookup not supported in MMDS.");
  }

  @Override
  public String getStageName() {
    return "stage";
  }

  @Override
  public String getNamespace() {
    return "default";
  }

  @Override
  public String getPipelineName() {
    return "pipeline";
  }

  @Override
  public long getLogicalStartTime() {
    return 0;
  }

  @Override
  public StageMetrics getMetrics() {
    return new StageMetrics() {
      @Override
      public void count(String s, int i) {
        // no-op
      }

      @Override
      public void gauge(String s, long l) {
        // no-op
      }

      @Override
      public void pipelineCount(String s, int i) {
        // no-op
      }

      @Override
      public void pipelineGauge(String s, long l) {
        // no-op
      }
    };
  }

  @Override
  public PluginProperties getPluginProperties() {
    return pluginContext.getPluginProperties("wrangler");
  }

  @Override
  public PluginProperties getPluginProperties(String s) {
    return pluginContext.getPluginProperties(s);
  }

  @Override
  public <T> Class<T> loadPluginClass(String s) {
    return pluginContext.loadPluginClass(s);
  }

  @Override
  public <T> T newPluginInstance(String s) throws InstantiationException {
    return pluginContext.newPluginInstance("s");
  }

  @Nullable
  @Override
  public Schema getInputSchema() {
    return null;
  }

  @Override
  public Map<String, Schema> getInputSchemas() {
    return Collections.emptyMap();
  }

  @Nullable
  @Override
  public Schema getOutputSchema() {
    return null;
  }

  @Override
  public Map<String, Schema> getOutputPortSchemas() {
    return Collections.emptyMap();
  }

  @Override
  public Arguments getArguments() {
    return new Arguments() {
      @Override
      public boolean has(String s) {
        return false;
      }

      @Nullable
      @Override
      public String get(String s) {
        return null;
      }

      @Override
      public Iterator<Map.Entry<String, String>> iterator() {
        return Collections.emptyIterator();
      }
    };
  }

  @Nullable
  @Override
  public URL getServiceURL(String applicationId, String serviceId) {
    return serviceDiscoverer.getServiceURL(applicationId, serviceId);
  }

  @Nullable
  @Override
  public URL getServiceURL(String serviceId) {
    return serviceDiscoverer.getServiceURL(serviceId);
  }

  @Override
  public Map<MetadataScope, Metadata> getMetadata(MetadataEntity metadataEntity) {
    return Collections.emptyMap();
  }

  @Override
  public Metadata getMetadata(MetadataScope metadataScope, MetadataEntity metadataEntity) {
    return new Metadata(Collections.emptyMap(), Collections.emptySet());
  }

  @Override
  public void addProperties(MetadataEntity metadataEntity, Map<String, String> map) {
    // no-op
  }

  @Override
  public void addTags(MetadataEntity metadataEntity, String... strings) {
    // no-op
  }

  @Override
  public void addTags(MetadataEntity metadataEntity, Iterable<String> iterable) {
    // no-op
  }

  @Override
  public void removeMetadata(MetadataEntity metadataEntity) {
    // no-op
  }

  @Override
  public void removeProperties(MetadataEntity metadataEntity) {
    // no-op
  }

  @Override
  public void removeProperties(MetadataEntity metadataEntity, String... strings) {
    // no-op
  }

  @Override
  public void removeTags(MetadataEntity metadataEntity) {
    // no-op
  }

  @Override
  public void removeTags(MetadataEntity metadataEntity, String... strings) {
    // no-op
  }

  @Override
  public void record(List<Operation> list) {
    // no-op
  }
}

@@ -552,16 +552,24 @@
 e.field.
+Pipeline
 Operatio
@@ -4868,16 +4868,24 @@
 rd(List%3C
+Pipeline
 Operatio
@@ -4891,12 +4891,26 @@
 on%3E 
-list
+pipelineOperations
 ) %7B%0A

Change 'Operation' to the 'PipelineOperation' per current field lineage api.