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

module Buildr
  module Wsgen
    class << self

      # :call-seq:
      #    java2wsdl(project, classnames, options) => String
      #
      # Uses wsgen to generate wsdl files form annotated, compiled classes. The parameters are
      # * :project -- The project in which the classes are compiled.
      # * :classnames -- Either an array of classnames to convert to wsdl or a map keyed on classnames and service
      #                  specific customizations provided.
      #
      # Service options include:
      # * :service_name -- The name of the service.
      # * :namespace_url -- The namespace of the service.
      #
      # Method options include:
      # * :output_dir -- The target directory.
      # * :namespace_url -- The default namespace for the services.
      #
      # For example:
      #  Buildr::Wsgen.java2wsdl(project, %w(com.example.MyService))
      #  Buildr::Wsgen.java2wsdl(project, %w(com.example.MyService com.example.MyOtherService))
      #  Buildr::Wsgen.java2wsdl(project, %w(com.example.MyService com.example.MyOtherService), :namespace_url => "http://example.com/services")
      #  Buildr::Wsgen.java2wsdl(project, {"com.example.MyService" => {:service_name => 'MiaService', :namespace_url => "http://example.com/it/services"}))
      def java2wsdl(project, classnames, options = {})
        desc 'Generate wsdl from java'
        project.task('java2wsdl').enhance([project.compile.target])

        base_wsdl_dir = File.expand_path(options[:output_dir] || project._(:target, :generated, :wsgen, :main, :wsdl))
        project.iml.main_generated_source_directories << base_wsdl_dir if project.iml?
        project.file(base_wsdl_dir)
        project.task('java2wsdl').enhance([base_wsdl_dir])

        services = classnames.is_a?(Array) ? classnames.inject({}) {|result, element| result[element] = {}; result} : classnames

        services.each_pair do |classname, config|

          name_parts = classname.split('.')
          service_name = config[:service_name] || name_parts.last
          namespace_url = config[:namespace_url] || options[:namespace_url] || "http://#{name_parts[0...-1].reverse.join('.')}"
          wsdl_file = File.expand_path("#{base_wsdl_dir}/META-INF/wsdl/#{service_name}.wsdl")

          project.file(wsdl_file) do
            mkdir_p File.dirname(wsdl_file)
            cp = Buildr.artifacts(project.compile.dependencies + [project.compile.target]).map(&:to_s).join(File::PATH_SEPARATOR)

            java_dir = project._(:target, :ignored, :wsgen, :main, :java)
            intermediate_dir = project._(:target, :ignored, :wsgen, :main, :java)

            rm_rf java_dir
            rm_rf intermediate_dir
            mkdir_p java_dir
            mkdir_p intermediate_dir

            args = []
            args << '-keep'
            args << '-inlineSchemas' if (options[:inlineSchemas] && ENV_JAVA['java.version'] >= '1.7')
            args << '-wsdl'
            args << '-servicename'
            args << "{#{namespace_url}}#{service_name}"
            args << '-portname'
            args << "{#{namespace_url}}#{service_name}Port"
            args << '-d'
            args << intermediate_dir
            args << '-r'
            args << "#{base_wsdl_dir}/META-INF/wsdl"
            args << '-s'
            args << java_dir
            args << '-cp'
            args << cp
            args << classname

            command = "wsgen #{args.join(' ')}"
            trace command
            sh command
            if $? != 0
              raise 'Problem building wsdl'
            end

            content = IO.read(wsdl_file).gsub('REPLACE_WITH_ACTUAL_URL', "http://example.com/#{service_name}")
            File.open(wsdl_file, 'wb') { |f| f.write content }
          end

          project.file(base_wsdl_dir).enhance([wsdl_file])
          project.task('java2wsdl').enhance([wsdl_file])
        end

        base_wsdl_dir
      end

      # :call-seq:
      #    wsdl2java(project, wsdls, options) => String
      #
      # Uses wsgen to generate java files form wsdls. The parameters are
      # * :project -- The project in which the classes are compiled.
      # * :wsdls -- A hash of wsdl filenames to service configuration.
      #
      # Service options include:
      # * :service_name -- The name of the service.
      # * :package -- The package in which to generate the code.
      # * :extension -- Should we allow non-portable extensions.
      #
      # Method options include:
      # * :output_dir -- The target directory.
      # * :target -- The target version for generated source..
      # * :package -- The default package in which to generate the code.
      #
      # For example:
      #  Buildr::Wsgen.wsdl2java(project, {_('src/main/wsdl/MyService.wsdl') => {}})
      #  Buildr::Wsgen.wsdl2java(project, {_('src/main/wsdl/MyService.wsdl') => {:package => 'com.example'}})
      #  Buildr::Wsgen.wsdl2java(project, {_('src/main/wsdl/MyService.wsdl') => {:output_dir => _(:target, :wsdl, :java)}})
      #  Buildr::Wsgen.wsdl2java(project, {_('src/main/wsdl/MyService.wsdl') => {}}, :package => 'com.example' )
      #  Buildr::Wsgen.wsdl2java(project, {_('src/main/wsdl/MyService.wsdl') => {}}, :wsdl_location => 'file:META-INF/wsdl/SpecificTaskService.wsdl' )
      def wsdl2java(project, wsdls, options = {})
        desc 'Generate java from wsdl'
        project.task('wsdl2java')

        ws_dir = File.expand_path(options[:output_dir] || project._(:target, :generated, 'ws/main/java'))
        project.file(ws_dir)
        project.task('wsdl2java').enhance([ws_dir])

        target = options[:target] || '2.1'

        wsdls.each_pair do |wsdl_file, config|
          pkg = config[:package] || options[:package]
          service = config[:service] || File.basename(wsdl_file, '.wsdl')
          wsdl_location = config[:wsdl_location]
          java_file = "#{ws_dir}/#{pkg.gsub('.', '/')}/#{service}.java"
          project.file(java_file => [project.file(wsdl_file)]) do
            mkdir_p ws_dir
            command = []
            command << 'wsimport'
            command << '-keep'
            command << '-Xnocompile'
            command << '-target'
            command << target
            command << '-s'
            command << ws_dir
            command << '-p'
            command << pkg
            if config[:extension]
              command << '-extension'
            end
            if wsdl_location
              command << '-wsdllocation'
              command << wsdl_location
            end
            command << wsdl_file

            trace command.join(' ')
            output = `#{command.join(' ')}`
            if $? != 0
              rm_rf java_file
              puts output
              raise 'Problem building webservices'
            end
            unless File.exist?(java_file)
              puts output
              raise 'Problem building webservices'
            end
            if output =~ /\[WARNING\]/
              puts output
            end
          end
          project.file(ws_dir).enhance([java_file])
        end

        project.compile.from ws_dir
        project.iml.main_generated_source_directories << ws_dir if project.iml?
        project.compile.enhance(['wsdl2java'])

        ws_dir
      end
    end
  end
end
