require_dependency 'project'
require 'find'

module RedmineLe
  SVN_DIR = File.join(HOME, "subversion/repos")
  SVN_TEMPLATE = SVN_DIR + "/repository_template"
  SVN_URL = "http://localhost:#{HTTP_PORT}/svn"


  module ProjectPatch
    def self.included(base)
      base.extend(ClassMethods)
      base.send(:include, InstanceMethods)

      base.class_eval do
        unloadable
        after_create :setup_integration
        after_destroy :cleanup_integration
      end
    end

    module ClassMethods
    end

    module InstanceMethods
      def repository_available?
        module_enabled?(:repository) &&
          (repository.nil? || repository.url == repository_url)
      end

      def repository_path
        @repository_path ||= File.join(RedmineLe::SVN_DIR, identifier)
      end

      def repository_url
        @repository_url ||= RedmineLe::SVN_URL + "/" + identifier
      end

      def hook_config
        @hook_config ||= HookConfig.new(self)
      end

      def setup_repository
        unless File.directory?(repository_path)
          target = RedmineLe::SVN_DIR + "/" + identifier
          FileUtils.cp_r(RedmineLe::SVN_TEMPLATE, target)
        end

        self.repository = Repository::Subversion.new(
          :url => repository_url,
          :root_url => repository_url,
          :login => RedmineLeSetting.admin_account,
          :password => RedmineLeSetting.admin_password
        )
        Repository.fetch_changesets

        %w[pre-commit.bat post-commit.bat].each {|filename|
          File.open(repository_path + "/hooks/#{filename}", "w") {|f|
            f.print(ERB.new(File.read(RedmineLe::TEMPLATE_DIR +
              "/#{filename}.erb")).result(binding))
          }
        }
      end

      def setup_job
        ldap = AuthSourceLdap.first
        url = repository_url
        auth_token = RedmineLe::Utils.random_string(20)
        data = ERB.new(File.read(RedmineLe::TEMPLATE_DIR + "/jenkins_job_config.xml.erb")).result(binding)

        Net::HTTP.start("localhost", RedmineLe::HTTP_PORT) {|http|
          response = http.post("/jenkins/createItem?name=#{identifier}", data, {
            "Content-Type" => "application/xml"
          })
          raise "Cannot create Jenkins job" unless response.code == "200"
        }

        hook_config["post_commit"]["perform_build"]["jobs"].push({
          "name" => identifier,
          "path" => "trunk"
        })
        hook_config.save
      end

      private
      def setup_integration
        return unless module_enabled?(:repository)

        setup_repository
        setup_job
      end

      def cleanup_integration
        FileUtils.rm_rf(repository_path)
        Net::HTTP.start("localhost", RedmineLe::HTTP_PORT) {|http|
          http.post("/jenkins/job/#{identifier}/doDelete", nil)
        }
      end
    end
  end
end
