#!/bin/bash

route_prefix=medical_check

err_report() {
    echo "$0: Error on line $1 - aborted"
    exit 1
}

trap 'err_report $LINENO' ERR

# Any failure causes exit
set -e

case "$1" in
[0-9]*)
    export BUNDLE_GEMFILE=$PWD/test/rails_$1.gemfile
    ;;
esac
while :
do
    case "$BUNDLE_GEMFILE" in
    */test/rails_[Qq].gemfile)
        echo "Aborting..."
        exit 2
        ;;
    */test/rails_edge.gemfile|*/test/rails_[0-9].[0-9]*.gemfile)
        if [ -f "$BUNDLE_GEMFILE" ]; then
            break
        fi
        ;;
    esac
    echo "== SELECT GEMFILE =="
    echo
    echo "Please select the gemfile for the required rails series:"
    (cd test ; ls rails*gemfile | ruby -p -e '$_.sub!(/rails_(.*).gemfile/, "    \\1")' )
    echo
    echo -n "Enter choice (or q to quit): "
    read x
    export BUNDLE_GEMFILE=$PWD/test/rails_$x.gemfile
done

if [ -z  "$MIDDLEWARE" ]; then
  echo -n "Add as middleware [N/y] : "
  read MIDDLEWARE
  export MIDDLEWARE
fi
rm -rf tmp/Gemfile* tmp/railsapp tmp/bin tmp/gems test/bin test/rails*.gemfile.lock

mkdir -p tmp/gems

. test/init_variables

if $rbenv_which bundle ; then
  echo Bundler is installed
else
  gem install bundler
  $rehash
fi

echo "Running bundle with BUNDLE_GEMFILE=$BUNDLE_GEMFILE ..."
if ! bundle install ; then
    echo "Test aborted (missing required gems)"
    exit 2
fi
$rehash

rails="$base_dir/test/bin/rails"
rake="$base_dir/test/bin/rake"

echo Checking $rails is present ...
[ -f $rails -a -f $rake ] || bundle exec rake rails:update:bin || echo '(ignored rake rails:update:bin exit status)'
[ -f $rails ] || bundle binstubs railties || echo '(ignored bundle exit status)'
[ -f $rails ] || bundle binstubs rails || echo '(ignored bundle exit status)'
if [ ! -f $rails ]; then
    echo "Test aborted (unable to create $rails)"
    exit 2
fi

if [ ! -f $rake ]; then
    echo "Running bundle binstubs rake ..."
    if ! bundle binstubs rake || [ ! -f $rake ]; then
        echo "Test aborted (unable to create $rake)"
        exit 2
    fi
fi

actual_rails_version=`$rails -v`

[ -d lib/health_check ] || exec echo setup_railsapp MUST be executed in the base of the health_check gem/clone of git repository

export GEM_PATH="$tmp_dir/gems:`gem environment gempath`"
echo Set GEM_PATH=$GEM_PATH

echo Installing health_check as a gem into $tmp_dir/gems
rm -f pkg/health_check-*.gem
if env GEM_HOME=$tmp_dir/gems $rake install
then
    echo rake install passed
else
    echo rake install failed! running gem install pkg/health_check-*.gem manually to see error message:
    env GEM_HOME=$tmp_dir/gems gem install pkg/health_check-*.gem
    echo gem install worked, but flagging it as a FAIL anyway since rake install failed!
    exit 2
fi

echo Gems in tmp/gems:
ls tmp/gems

echo Environment:
env | egrep 'TRAVIS|RAILS|RUBY|_ENV|GEM|BUNDLE' || echo "No relevant variables set"

cd $tmp_dir

case `ruby -e 'puts JRUBY_VERSION' 2> /dev/null` in
    [0-9]*)
        db=jdbcsqlite3
        # Appears to need a bit extra time
        ;;
    *)
        db=sqlite3
        ;;
esac

echo "Creating $actual_rails_version app in $tmp_dir/railsapp using adapter $db"
case "$actual_rails_version" in
    *' '[12].*)
        $rails railsapp -d $db
        ;;
    *' '[345].*)
        case "$BUNDLE_GEMFILE" in
        *rails_edge.gemfile)
            $rails new railsapp -d $db --edge
            ;;
        *)
            $rails new railsapp -d $db
            ;;
        esac
        ;;
    *)
        echo "Unknown rails version"
        ;;
esac

cd $railsapp

[ -z "$rehash" ] || rbenv local `rbenv version-name`

echo "Changed current directory to railsapp root: $railsapp"

echo "Fixing rdoc require in Rakefile if needed"
ruby -p -i.bak -e '$_.gsub!(/rake.rdoctask/, "rdoc/task")' Rakefile

echo "Configuring mailer to point to fake_smtp_server port 3555"
cat >> config/environment.rb <<'!EOF!'

ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = { :address => "localhost", :port => 3555 }

!EOF!

echo Adding an initializer for health_check gem ...
mkdir -p config/initializers
tee config/initializers/health_check.rb <<!
HealthCheck.setup do |config|
  config.success = "$success"
  config.smtp_timeout = 60.0
  config.http_status_for_error_text = 550
  config.http_status_for_error_object = 555
  config.uri = '$route_prefix'
  config.origin_ip_whitelist = ENV['IP_WHITELIST'].split(',') unless ENV['IP_WHITELIST'].blank?
  config.basic_auth_username = ENV['AUTH_USER'] unless ENV['AUTH_USER'].blank?
  config.basic_auth_password = ENV['AUTH_PASSWORD'] unless ENV['AUTH_PASSWORD'].blank?

  config.add_custom_check do
    File.exists?("$custom_file") ? '' : '$custom_file is missing!'
  end

  config.add_custom_check('pass') do
    ''
  end

end
!

echo Setting INITIAL_BUNDLE_GEMFILE=$BUNDLE_GEMFILE
INITIAL_BUNDLE_GEMFILE="$BUNDLE_GEMFILE"
echo Unsetting BUNDLE_GEMFILE '(so Gemfile for rails application will be used)'
unset BUNDLE_GEMFILE

if [ -s Gemfile ]
then
    echo Adding health_check as gem to Gemfile...
    echo "gem 'health_check', :path => '$base_dir'" >> Gemfile

    case "$RAILS_SERVER" in
    webrick|'')
            echo "Using default webrick server"
            ;;
    *)
            echo "Adding $RAILS_SERVER gem to Gemfile (for use as server)"
            echo "gem '$RAILS_SERVER'" >> Gemfile
            ;;
    esac
    egrep REQUIRED < ${INITIAL_BUNDLE_GEMFILE} >> Gemfile || echo No required gems found...
    echo
    echo ================= Gemfile ===================
    cat Gemfile
    echo
    echo running bundle install
    bundle install
    $rehash
    echo "Using binstubs in $railsapp/bin for rails and rake commands"
    rails="$railsapp/bin/rails"
    rake="$railsapp/bin/rake"

    echo Checking $rails is present ...
    [ -f $rails -a -f $rake ] || bundle exec rake rails:update:bin || echo '(ignored rake rails:update:bin exit status)'
    [ -f $rails ] || bundle binstubs railties || echo '(ignored bundle exit status)'
    [ -f $rails ] || bundle binstubs rails || echo '(ignored bundle exit status)'
    if [ ! -f $rails ]; then
        echo "Test aborted (unable to create $rails)"
        exit 2
    fi

    echo Checking $rake is present ...
    [ -f $rake ] || bundle binstubs rake || echo '(ignored bundle exit status)'
    if [ ! -f $rake ]; then
        echo "Test aborted (unable to create $rake)"
        exit 2
    fi

    $rehash
    # Fix for rvm, otherwise bundle run from rails create fails
    export PATH="`pwd`/bin:$PATH"
    echo ================= Gemfile.lock ===================
    cat Gemfile.lock
    echo
else
    dest=$railsapp/vendor/plugins/health_check
    echo Installing health_check as plugin in $dest ...
    mkdir -p $dest
    (
	cd $base_dir

        git ls-files | cpio -pdl $dest
        
	cd $dest

        echo Files installed as plugin:
        find . -type f
        echo
    )
fi

for e in test ${RAILS_ENV2:-production}
do
    if [ -f config/environments/$e.rb ]; then
      echo ======== config/environments/$e.rb ================
      sed -i.bak -e 's/config.serve_static_assets = false/config.serve_static_assets = true   # NOTE: health_check test: changed to true/'  \
        -e 's/config.active_record.migration_error = :page_load/# & # NOTE: health_check test: commented out/'  \
        config/environments/$e.rb 
      cat config/environments/$e.rb || true
      echo
    fi
done
echo "============== config/environment.rb ============="
cat config/environment.rb
echo 

echo ========================
case $db in
    jdbcsqlite3)
      for e in test ${RAILS_ENV2:-production}
      do
            echo
            export RAILS_ENV=$e RACK_ENV=$e
            echo "Jruby requires the database to be created before the server is started: running RAILS_ENV=$e rake db:migrate"
            $rake db:migrate 
            echo
      done
      ;;
esac

echo STATIC-FILE > public/static.txt

cat > public/ajax_example.html <<'EOF'
    <html>
    <head>
      <title>Example static and dynamic calls to health_check</title>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <script>
	function parse_result(result, callback) {
	    $("#html_status_"+callback).text(result.status);
	    $("#html_body_"+callback).text(result.responseText);
	    alert(callback + " callback called");
	};

	function dynamic_call(dataType, url) {
	  $.ajax({
	    dataType: dataType,
	    url: url,
	    success: function(data, textStatus, result) {
	      $("#data_success").text(data);
	      parse_result(result, "success");
	    },
	    error: function(result, textStatus) {
	      parse_result(result, "error");
	    },
	    complete: function(result, textStatus) {
	      parse_result(result, "complete");
	    }
	  });
	};
      </script>
    </head>
    <body>
      <h1>Static calls</h1>
      <ul>
	<li><a href="http://localhost:3000/health_check/site" target="_blank">Minimal health check should always work</a>
	  (<a href="http://localhost:3000/health_check/site.json" target="_blank">json</a>,
	  <a href="http://localhost:3000/health_check/site.xml" target="_blank">xml</a>,
	  <a href="http://localhost:3000/health_check/site.html" target="_blank">html</a>)
	<li><a href="http://localhost:3000/health_check/fail" target="_blank">Force health check to fail!</a>
	  (<a href="http://localhost:3000/health_check/fail.json" target="_blank">json</a>,
	  <a href="http://localhost:3000/health_check/fail.xml" target="_blank">xml</a>,
	  <a href="http://localhost:3000/health_check/fail.html" target="_blank">html</a>)
      </ul>
      <h1>Dynamic calls</h1>
      <ul>
	<li><a href="#" onclick="dynamic_call('text', 'http://localhost:3000/health_check/site');">Minimal health check should always work</a>
	  (<a href="#" onclick="dynamic_call('json', 'http://localhost:3000/health_check/site.json');">json</a>,
	  <a href="#" onclick="dynamic_call('xml', 'http://localhost:3000/health_check/site.xml');">xml</a>,
	  <a href="#" onclick="dynamic_call('text', 'http://localhost:3000/health_check/site.html');">html</a>)

	<li><a href="#" onclick="dynamic_call('text', 'http://localhost:3000/health_check/fail');">Force health check to fail!</a>
	  (<a href="#" onclick="dynamic_call('json', 'http://localhost:3000/health_check/fail.json');">json</a>,
	  <a href="#" onclick="dynamic_call('xml', 'http://localhost:3000/health_check/fail.xml');">xml</a>,
	  <a href="#" onclick="dynamic_call('text', 'http://localhost:3000/health_check/fail.html');">html</a>)
	<li>Last results sent to success:<ul>
	  <li><b>Data:</b><span id=data_success></span>
	  <li><b>result.status:</b><span id=html_status_success></span>
	  <li><b>result.responseText:</b><span id=html_body_success></span>
	</ul>
	<li>Last results sent to error:<ul>
	  <li><b>result.status:</b><span id=html_status_error></span>
	  <li><b>result.responseText:</b><span id=html_body_error></span>
	</ul>
	<li>Last results sent to complete:<ul>
	  <li><b>result.status:</b><span id=html_status_complete></span>
	  <li><b>result.responseText:</b><span id=html_body_complete></span>
	</ul>
      </ul>
    </body>
    </html>
EOF

cat > app/controllers/example_controller.rb <<'EOF'
class ExampleController < ApplicationController

  def index
    render :text => 'example page'
  end
  
  def catchall
    render :text => 'catch all route'
  end
  
end

EOF

echo =======================================

case "$MIDDLEWARE" in
[Yy]*)
  if [ -s config/application.rb ]; then
    mv -f config/application.rb config/application.rb-old
    (
      ruby -n -e 'print if not /^  *end/..9999' config/application.rb-old | tee /tmp/t$$
      if [ ! -s /tmp/t$$ ]; then
        echo "WARNING: ruby -n -e failed silently - using sed instead!! (rbx-19mode has that problem)" >&3
        sed -e '/^  *end/,$d' config/application.rb-old
      fi

      echo "    # -----------------------------------------"
      echo "    # START OF SECTION FOR TESTING HEALTH_CHECK"
      echo "    config.middleware.insert_after 'Rails::Rack::Logger', HealthCheck::MiddlewareHealthcheck"
      echo "    # END OF SECTION FOR TESTING HEALTH_CHECK"
      echo "    # ---------------------------------------"
      ruby -n -e 'print if /^  *end/..9999' config/application.rb-old | tee /tmp/t$$
      if [ ! -s /tmp/t$$ ]; then
        echo "WARNING: ruby -n -e failed silently - using sed instead!! (rbx-19mode has that problem)" >&3
        sed -n -e '/^  *end/,$p' config/application.rb-old
      fi
    ) 3>&1 > config/application.rb

    #echo =============== config/application.rb-old ========================
    #cat config/application.rb-old
    echo =============== config/application.rb ========================
    cat config/application.rb
  else
    echo FAILED: NO config/application.rb file!!
    exit 2
  fi

  echo =======================================

  ;;
esac

if [ -s config/routes.rb ]; then
  mv -f config/routes.rb config/routes.rb-old
  (
    ruby -n -e 'print if not /^end/..9999' config/routes.rb-old | tee /tmp/t$$
    if [ ! -s /tmp/t$$ ]; then
      echo "WARNING: ruby -n -e failed silently - using sed instead!! (rbx-19mode has that problem)" >&3
      sed -e '/^end/,$d' config/routes.rb-old
    fi

    # rails 3.0+
    echo "  # -----------------------------------------"
    echo "  # START OF SECTION FOR TESTING HEALTH_CHECK"
    echo "  get 'example(/:action(/:id))(.:format)' => 'example'"
    echo "  if File.exists?('$catchall_file')"
    echo "    health_check_routes"
    echo "    # CATCH ALL ROUTE"
    echo "    get '*path', :to => 'example#catchall'"
    echo "  end"
    echo "  # END OF SECTION FOR TESTING HEALTH_CHECK"
    echo "  # ---------------------------------------"
    ruby -n -e 'print if /^end/..9999' config/routes.rb-old | tee /tmp/t$$
    if [ ! -s /tmp/t$$ ]; then
      echo "WARNING: ruby -n -e failed silently - using sed instead!! (rbx-19mode has that problem)" >&3
      sed -n -e '/^end/,$p' config/routes.rb-old
    fi
  ) 3>&1 > config/routes.rb

  #echo =============== config/routes.rb-old ========================
  #cat config/routes.rb-old
  echo =============== config/routes.rb ========================
  cat config/routes.rb
else
  echo FAILED: NO config/routes.rb file!!
  exit 2
fi
echo =======================================

echo
echo "Created $actual_rails_version app in $railsapp using adapter $db"
echo -n "Using "
ruby --version
