// Copyright (C) 2014 The Android Open Source Project
//
// Licensed 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 com.ericsson.gerrit.plugins.eventslog.sql;

import static com.ericsson.gerrit.plugins.eventslog.sql.SQLTable.DATE_ENTRY;
import static com.ericsson.gerrit.plugins.eventslog.sql.SQLTable.PRIMARY_ENTRY;
import static com.ericsson.gerrit.plugins.eventslog.sql.SQLTable.TABLE_NAME;

import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.ericsson.gerrit.plugins.eventslog.EventsLogConfig;
import com.ericsson.gerrit.plugins.eventslog.MalformedQueryException;
import com.ericsson.gerrit.plugins.eventslog.QueryMaker;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

@Singleton
class SQLQueryMaker implements QueryMaker {
  private static final int TWO = 2;
  private static final String TIME_ONE = "t1";
  private static final String TIME_TWO = "t2";
  private static final ThreadLocal<DateFormat> DATE_TIME_FORMAT =
      new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
          return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
      };
  private static final ThreadLocal<DateFormat> DATE_ONLY_FORMAT =
      new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
          return new SimpleDateFormat("yyyy-MM-dd");
        }
      };

  private final int returnLimit;

  @Inject
  SQLQueryMaker(EventsLogConfig config) {
    this.returnLimit = config.getReturnLimit();
  }

  @Override
  public String formQueryFromRequestParameters(Map<String, String> params)
      throws MalformedQueryException {
    if (params == null) {
      return getDefaultQuery();
    }
    Date[] dates;
    try {
      dates = parseDates(params.get(TIME_ONE), params.get(TIME_TWO));
    } catch (ParseException e) {
      throw new MalformedQueryException(e);
    }
    return String.format(
        "SELECT * FROM %s WHERE %s BETWEEN '%s' and '%s' LIMIT %d", TABLE_NAME,
        DATE_ENTRY, DATE_TIME_FORMAT.get().format(dates[0]),
        DATE_TIME_FORMAT.get().format(dates[1]), returnLimit);
  }

  @Override
  public String getDefaultQuery() {
    return "SELECT * FROM(SELECT * FROM " + TABLE_NAME
        + " ORDER BY " + PRIMARY_ENTRY + " DESC LIMIT " + returnLimit + ")"
        + " a ORDER BY " + PRIMARY_ENTRY + " ASC";
  }

  private Date[] parseDates(String dateOne, String dateTwo)
      throws MalformedQueryException, ParseException {
    Calendar cal = Calendar.getInstance();
    if (dateOne == null & dateTwo == null) {
      throw new MalformedQueryException();
    }
    Date[] dates = new Date[TWO];
    Date dOne =
        dateOne == null && dateTwo != null ? cal.getTime() : parseDate(dateOne);
    Date dTwo =
        dateTwo == null && dateOne != null ? cal.getTime() : parseDate(dateTwo);
    dates[0] = dOne.compareTo(dTwo) < 0 ? dOne : dTwo;
    dates[1] = dOne.compareTo(dTwo) < 0 ? dTwo : dOne;
    return dates;
  }

  private Date parseDate(String date) throws ParseException {
    Date parsedDate;
    try {
      parsedDate = DATE_TIME_FORMAT.get().parse(date);
    } catch (ParseException e) {
      parsedDate = DATE_ONLY_FORMAT.get().parse(date);
    }
    return parsedDate;
  }
}
