/*
 * Druid - a distributed column store.
 * Copyright (C) 2012  Metamarkets Group Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package com.metamx.druid.db;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.metamx.common.MapUtils;
import com.metamx.common.concurrent.ScheduledExecutors;
import com.metamx.common.lifecycle.LifecycleStart;
import com.metamx.common.lifecycle.LifecycleStop;
import com.metamx.common.logger.Logger;
import com.metamx.druid.master.rules.PeriodLoadRule;
import com.metamx.druid.master.rules.Rule;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.joda.time.Period;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.FoldController;
import org.skife.jdbi.v2.Folder3;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.StatementContext;
import org.skife.jdbi.v2.tweak.HandleCallback;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicReference;

/**
 */
public class DatabaseRuleManager
{
  public static void createDefaultRule(final DBI dbi, final String ruleTable, final ObjectMapper jsonMapper)
  {
    try {
      dbi.withHandle(
          new HandleCallback<Void>()
          {
            @Override
            public Void withHandle(Handle handle) throws Exception
            {
              List<Map<String, Object>> existing = handle.select(
                  String.format(
                      "SELECT id from %s where datasource='_default';",
                      ruleTable
                  )
              );

              if (!existing.isEmpty()) {
                return null;
              }

              final List<Rule> defaultRules = Arrays.<Rule>asList(
                  new PeriodLoadRule(
                      new Period("P5000Y"),
                      2,
                      "_default_tier"
                  )
              );
              final String dataSource = "_default";
              final String version = new DateTime().toString();
              handle.createStatement(
                  String.format(
                      "INSERT INTO %s (id, dataSource, version, payload) VALUES (:id, :dataSource, :version, :payload)",
                      ruleTable
                  )
              )
                    .bind("id", String.format("%s_%s", dataSource, version))
                    .bind("dataSource", dataSource)
                    .bind("version", version)
                    .bind("payload", jsonMapper.writeValueAsString(defaultRules))
                    .execute();

              return null;
            }
          }
      );
    }
    catch (Exception e) {
      throw Throwables.propagate(e);
    }
  }

  private static final Logger log = new Logger(DatabaseRuleManager.class);

  private final ObjectMapper jsonMapper;
  private final ScheduledExecutorService exec;
  private final DatabaseRuleManagerConfig config;
  private final DBI dbi;
  private final AtomicReference<ConcurrentHashMap<String, List<Rule>>> rules;

  private final Object lock = new Object();

  private volatile boolean started = false;

  public DatabaseRuleManager(
      ObjectMapper jsonMapper,
      ScheduledExecutorService exec,
      DatabaseRuleManagerConfig config,
      DBI dbi
  )
  {
    this.jsonMapper = jsonMapper;
    this.exec = exec;
    this.config = config;
    this.dbi = dbi;

    this.rules = new AtomicReference<ConcurrentHashMap<String, List<Rule>>>(
        new ConcurrentHashMap<String, List<Rule>>()
    );
  }

  @LifecycleStart
  public void start()
  {
    synchronized (lock) {
      if (started) {
        return;
      }

      ScheduledExecutors.scheduleWithFixedDelay(
          exec,
          new Duration(0),
          config.getRulesPollDuration(),
          new Runnable()
          {
            @Override
            public void run()
            {
              poll();
            }
          }
      );

      started = true;
    }
  }

  @LifecycleStop
  public void stop()
  {
    synchronized (lock) {
      if (!started) {
        return;
      }

      rules.set(new ConcurrentHashMap<String, List<Rule>>());

      started = false;
    }
  }

  public void poll()
  {
    try {
      ConcurrentHashMap<String, List<Rule>> newRules = new ConcurrentHashMap<String, List<Rule>>(
          dbi.withHandle(
              new HandleCallback<Map<String, List<Rule>>>()
              {
                @Override
                public Map<String, List<Rule>> withHandle(Handle handle) throws Exception
                {
                  return handle.createQuery(
                      String.format("SELECT dataSource, payload FROM %s", config.getRuleTable())
                  ).fold(
                      Maps.<String, List<Rule>>newHashMap(),
                      new Folder3<Map<String, List<Rule>>, Map<String, Object>>()
                      {
                        @Override
                        public Map<String, List<Rule>> fold(
                            Map<String, List<Rule>> retVal,
                            Map<String, Object> stringObjectMap,
                            FoldController foldController,
                            StatementContext statementContext
                        ) throws SQLException
                        {

                          try {
                            String dataSource = MapUtils.getString(stringObjectMap, "dataSource");
                            List<Rule> rules = jsonMapper.readValue(
                                MapUtils.getString(stringObjectMap, "payload"), new TypeReference<List<Rule>>()
                            {
                            }
                            );
                            retVal.put(dataSource, rules);
                            return retVal;
                          }
                          catch (Exception e) {
                            throw Throwables.propagate(e);
                          }
                        }
                      }
                  );
                }
              }
          )
      );

      log.info("Polled and found rules for %,d datasource(s)", newRules.size());

      rules.set(newRules);
    }
    catch (Exception e) {
      log.error(e, "Exception while polling for rules");
    }
  }

  public Map<String, List<Rule>> getAllRules()
  {
    return rules.get();
  }

  public List<Rule> getRules(final String dataSource)
  {
    return rules.get().get(dataSource);
  }

  public List<Rule> getRulesWithDefault(final String dataSource)
  {
    List<Rule> retVal = Lists.newArrayList();
    Map<String, List<Rule>> theRules = rules.get();
    if (theRules.get(dataSource) != null) {
      retVal.addAll(theRules.get(dataSource));
    }
    if (theRules.get(config.getDefaultDatasource()) != null) {
      retVal.addAll(theRules.get(config.getDefaultDatasource()));
    }
    return retVal;
  }

  public boolean overrideRule(final String dataSource, final List<Rule> newRules)
  {
    synchronized (lock) {
      try {
        dbi.withHandle(
            new HandleCallback<Void>()
            {
              @Override
              public Void withHandle(Handle handle) throws Exception
              {
                final String version = new DateTime().toString();
                handle.createStatement(
                    String.format(
                        "INSERT INTO %s (id, dataSource, version, payload) VALUES (:id, :dataSource, :version, :payload)",
                        config.getRuleTable()
                    )
                )
                      .bind("id", String.format("%s_%s", dataSource, version))
                      .bind("dataSource", dataSource)
                      .bind("version", version)
                      .bind("payload", jsonMapper.writeValueAsString(newRules))
                      .execute();

                return null;
              }
            }
        );

        ConcurrentHashMap<String, List<Rule>> existingRules = rules.get();
        if (existingRules == null) {
          existingRules = new ConcurrentHashMap<String, List<Rule>>();
        }
        existingRules.put(dataSource, newRules);
      }
      catch (Exception e) {
        log.error(e, String.format("Exception while overriding rule for %s", dataSource));
        return false;
      }
    }

    return true;
  }
}
