# Author: Sacha IFRAH <sifrah>
# Date:   11/Nov/2016
# Project: NasOnlines
# Last modified by:   sifrah
# Last modified time: 11/Nov/2016
# License: MIT License

# Copyright (c) 2016 NasOnlines SAS
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

require_relative '../config/config.rb'
require "sqlite3"

class Database

  attr_accessor :semaphore
  attr_accessor :database

  def initialize()
    Log.info("DB", "Initialize database")
    self.semaphore = Mutex.new
    self.loadDatabase
  end

  def create(key, value)
    self.database.execute "INSERT INTO indexing (file_path, file_sent, last_edit)
      VALUES ('#{key}', '#{value[:sent].to_s}', '#{value[:last_edit].to_s}')"
  end

  def update(key, value)
    self.database.execute "UPDATE indexing
      SET file_sent='#{value[:sent].to_s}', last_edit='#{value[:last_edit].to_s}' WHERE file_path='#{key.to_s}'"
  end

  def delete(key)
    self.database.execute "DELETE FROM indexing WHERE file_path='#{key.to_s}'"
  end

  def find (key)
    self.semaphore.synchronize {
      ret = self.database.execute( "SELECT * FROM indexing WHERE file_path = '#{key.to_s}' LIMIT 1" )
      return false if ret.count == 0
      return self.format_response(ret)
    }
  end

  def find_multiple_key(keys)
    sql_request = "SELECT * FROM indexing WHERE file_path IN ("
    i = 1
    keys.each do |path|
      sql_request = "#{sql_request}'#{path}'"
      if i < keys.count
        sql_request = "#{sql_request}, "
      end
      i = i + 1
    end
    sql_request = "#{sql_request}) "
    toReturn = []
    self.semaphore.synchronize {
      ret = self.database.execute(sql_request)
      return [] if ret.count == 0
      return self.format_response(ret)
    }
  end

  def find_all(offset)
    ret = self.database.execute("SELECT * FROM indexing LIMIT #{$dbLimit} OFFSET #{offset}")
    return false if ret.count == 0
    self.format_response(ret)
  end

  def find_all_not_sent(offset)
    ret = self.database.execute("SELECT * FROM indexing WHERE file_sent='false' LIMIT #{$dbLimit} OFFSET #{offset} ")
    return [] if ret.count == 0
    self.format_response(ret)
  end

  def find_all_already_sent(offset)
    ret = self.database.execute("SELECT * FROM indexing WHERE file_sent='true' LIMIT #{$dbLimit} OFFSET #{offset}")
    return false if ret.count == 0
    self.format_response(ret)
  end

  def count_need_to_sent
    ret = self.database.execute("SELECT COUNT(file_path) FROM indexing WHERE file_sent='false'")[0][0]
    return ret.to_i
  end

  def count
    self.database.execute("SELECT COUNT(file_path) FROM indexing;")[0][0]
  end

  def loadDatabase
    begin
      file = File.open($path_database_file, "r")
      self.database = SQLite3::Database.new $path_database_file
      file.close
      Log.success("DB", "Database successfuly loaded")
    rescue
      Log.success("DB", "Creating database ...")
      self.database = SQLite3::Database.new $path_database_file
      self.initDatabase
    end
    self.database.busy_timeout = 5000
  end

  def initDatabase
    rows = self.database.execute <<-SQL
      create table indexing (
        file_path TEXT,
        file_sent BOOLEAN,
        last_edit VARCHAR(255)
      );
    SQL
    Log.success("DB", "Database successfuly created !")
  end

  def format_response (array)
    newArr = []
    keys = ["file_path", "sent", "last_edit"]
    array.each do |line|
      newArr << line.each_with_index.map { |v, i| { keys[i] => v } }.reduce(:merge).to_json
    end
    return JSON.parse(newArr.to_json)
  end

end
