#
#    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.
#

SETTINGS = "#{File.expand_path('.buildr', ENV['HOME'])}/settings.rb"

module NativeDB
#
  if File.exist? SETTINGS
    require SETTINGS
    Java.rjb.onload { Java.rjb.classpath << REQUIRES  }
  end

  class << self

    def create_dbs(buildr, base, orm)
      if File.exist? SETTINGS
        require SETTINGS

        settings().each do |name, dbprops|
          if dbprops[:db] != "derby"
            buildr.build create_hib_db(name, "#{base}/target/#{name}"=>dbprops) if orm == :hib and dbprops[:dao].downcase.include? "hib"
            buildr.build create_jpa_db(base, name, "#{base}/target/#{name}"=>dbprops) if orm == :jpa and !dbprops[:dao].downcase.include? "hib"
          end
        end
      end
    end

    def create_hib_db(name, args)
      if File.exist? SETTINGS
        require SETTINGS
        db, dbprops = args.keys.first, args.values.first
        file(File.expand_path(db)) do |task|
          puts "Creating(preparing) database: #{db}."
          rm_rf task.name if File.exist?(task.name)
          Dir.mkdir(task.name)
          Buildr.ant(name) do |ant|
            create_tables_sql = "#{task.name}/ode_tables.sql"
            drop_tables_sql = "#{task.name}/drop_ode_tables.sql"
            ant.get :src=>"http://release.intalio.com/m2repo/ci-resources/ode-schema-5.2.x/package/#{dbprops[:db]}/ode_tables.sql",
                    :dest=> create_tables_sql
            sqls = prepare_sqls(task, ant, [], :hib, dbprops[:db], drop_tables_sql, create_tables_sql)

            # Apply the sql scripts to the database
            ant.sql :driver=>dbprops[:driver], :url=>dbprops[:url], :userid=>dbprops[:userid], :password=>dbprops[:password], :autocommit=>dbprops[:autocommit] do
              sqls.each { |sql| ant.transaction :src=>sql }
            end
            puts "Created(prepared) database: #{dbprops[:url]}."
          end
        end
      end
    end

    def create_jpa_db(base, name, args)
      if File.exist? SETTINGS
        require SETTINGS
        db, dbprops = args.keys.first, args.values.first
        file(File.expand_path(db)) do |task|
          puts "Creating(preparing) database: #{db}."
          rm_rf task.name if File.exist?(task.name)
          Dir.mkdir(task.name)
          Buildr.ant(name) do |ant|
            create_tables_sql = "#{base}/target/#{dbprops[:db]}.sql"
            drop_tables_sql = "#{task.name}/drop-#{dbprops[:db]}.sql"
            sqls = prepare_sqls(task, ant, [], :jpa, dbprops[:db], drop_tables_sql, create_tables_sql)

            # Apply the sql scripts to the database
            ant.sql :driver=>dbprops[:driver], :url=>dbprops[:url], :userid=>dbprops[:userid], :password=>dbprops[:password], :autocommit=>dbprops[:autocommit] do
              sqls.each { |sql| ant.transaction :src=>sql }
            end
            puts "Created(prepared) database: #{dbprops[:url]}."
          end
        end
      end
    end

    def prepare_configs(test, base)
      test.setup task("prepare_configs") do |task|
        if File.exist? SETTINGS
          require SETTINGS

          hibdbs = ""
          jpadbs = ""
          settings().each do |name, dbprops|
            dbs = (dbprops[:dao].downcase.include? "hib") ? hibdbs : jpadbs
            if dbprops[:db] == "derby"
              dbs <<= ", " if dbs.length > 0
              dbs <<= (dbs == jpadbs ? "<jpa>" : "<hib>")
            else
              test.with REQUIRES

              prepare_config(name, dbprops, "#{base}/target/conf.#{name}", "#{base}/src/test/webapp/WEB-INF/conf.template")
              dbs <<= ", " if dbs.length > 0
              dbs <<= "#{base}/target/conf.#{name}"
            end
          end
           test.options[:properties]["org.apache.ode.hibdbs"] = hibdbs
           test.options[:properties]["org.apache.ode.jpadbs"] =jpadbs
        end
      end
    end

    def prepare_config(name, dbprops, db, template)
      rm_rf db if File.exist?(db)
      Dir.mkdir(db)

      Buildr.ant(name) do |ant|
        ant.copy :todir=>db do
          ant.fileset :dir=>template
        end

        ant.replace :file=>"#{db}/ode-axis2.properties", :token=>"@connfactory@", :value=>dbprops[:dao]
        ant.replace :file=>"#{db}/ode-axis2.properties", :token=>"@driver@", :value=>dbprops[:driver]
        ant.replace :file=>"#{db}/ode-axis2.properties", :token=>"@url@", :value=>dbprops[:url]
        ant.replace :file=>"#{db}/ode-axis2.properties", :token=>"@userid@", :value=>dbprops[:userid]
        ant.replace :file=>"#{db}/ode-axis2.properties", :token=>"@password@", :value=>dbprops[:password]

        puts "Created config directory: #{db}."
      end
    end

    def prepare_sqls(task, ant, sql_files, orm, db, drop_tables_sql, create_tables_sql)
      # read the create table sql into a string
      create_tables = ""
      File.open(create_tables_sql, "r") do |f1|
        while line = f1.gets
          create_tables <<= line
        end
      end

      # create the drop table sql file from the create table sql
      if orm == :hib and db == "sqlserver"
        File.open(drop_tables_sql, "w") do |f2|
          create_tables.gsub(/CREATE TABLE (.*?)[\s\(].*?;/mi) { |match|
            f2.puts "IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME='" << $1 << "') DROP TABLE " << $1 << ";\n"
          }
          # remove the 'go's in the sql
          f2.puts create_tables.gsub(/\ngo[\n$]/mi, "\n")
        end
        # add in the drop table sql file
        sql_files |= [drop_tables_sql]
      elsif orm == :jpa and db == "mysql"
        File.open(drop_tables_sql, "w") do |f2|
          create_tables.gsub(/CREATE TABLE (.*?)[\s\(].*?;/m) { |match|
            f2.puts "DROP TABLE IF EXISTS " << $1 << ";\n"
          }
        end
        # add in the drop table sql file
        sql_files |= [drop_tables_sql]
      end

      # add in the create table sql file
      if orm == :hib and db != "sqlserver"
        ant.copy :file=>create_tables_sql, :tofile=>"#{task.name}/#{db}.sql"
        sql_files |= ["#{task.name}/#{db}.sql"]
      elsif orm == :jpa
        ant.copy :file=>create_tables_sql, :tofile=>"#{task.name}/#{db}.sql"
        sql_files |= ["#{task.name}/#{db}.sql"]
      end

      sql_files
    end

  protected

    # This will download all the required artifacts before returning a classpath, and we want to do this only once.
    def requires()
      @requires ||= Buildr.artifacts(REQUIRES).each(&:invoke).map(&:to_s).join(File::PATH_SEPARATOR)
    end
  end
end
