class Admin::SitePanelController < OrbitAdminController
  require "rake"
  begin
    Rails.application.load_tasks
  rescue => e
    puts "Load tasks failed."
    puts e.to_s
  end
  before_action :check_server_ability, only: [:index,:server_manager]
  def initialize
    super
    @app_title = "client_management"
  end
  Is_Rails5 = (Rails.version.to_i > 4)
  def can_use
    ClientManagerSetting.create if ClientManagerSetting.count == 0
    setting = ClientManagerSetting.first
    if setting.enable_api && setting.api_key == params[:api_key]
      @allow_api = true
      if params[:id].blank? && params[:domain_name].present?
        params[:id] =  SiteConstruct.where(:domain_name=>/#{params[:domain_name].gsub(".","\\.")}/).first.id rescue nil
      end
      return true
    else
      return super
    end
  end
  def current_user
    if @allow_api
      return User.where(:user_name=>'admin').first
    else
      return super
    end
  end
  def authenticate_user
    ClientManagerSetting.create if ClientManagerSetting.count == 0
    setting = ClientManagerSetting.first
    if setting.enable_api && setting.api_key == params[:api_key]
      @allow_api = true
      if params[:id].blank? && params[:domain_name].present?
        params[:id] =  SiteConstruct.where(:domain_name=>/#{params[:domain_name].gsub(".","\\.")}/).first.id rescue nil
      end
      return true
    else
      return super
    end
  end
  def super_manager_management
    @site_server = SiteServer.find(params[:id])
  end
  def update_super_manager_management
    @site_server = SiteServer.find(params[:id])
    site_server_params = params.require(:site_server).permit! rescue {}
    removed_super_users = []
    site_server_params["site_super_users_attributes"].each do |k, v|
      if v["_destroy"] == 'true'
        super_user = SiteSuperUser.find(v["id"])
        if super_user.old_user_name.nil?
          removed_super_users << super_user.user_name
        elsif super_user.old_user_name != ''
          removed_super_users << super_user.old_user_name
        end
      end
    end if site_server_params["site_super_users_attributes"]
    @site_server.update_attributes(site_server_params)
    @site_server.check_super_user_changed
    if removed_super_users.count != 0
      @site_server.removed_super_users += removed_super_users
      @site_server.super_user_changed = true
      @site_server.save
    end
    redirect_back_custom
  end
  def super_manager_management_for_site
    @site_construct = SiteConstruct.find(params[:id])
  end
  def update_super_manager_management_for_site
    @site_construct = SiteConstruct.find(params[:id])
    site_construct_params = params.require(:site_construct).permit! rescue {}
    removed_super_users = []
    site_construct_params["site_super_users_attributes"].each do |k, v|
      if v["_destroy"] == 'true'
        super_user = SiteSuperUser.find(v["id"])
        if super_user.old_user_name.nil?
          removed_super_users << super_user.user_name
        elsif super_user.old_user_name != ''
          removed_super_users << super_user.old_user_name
        end
      end
    end if site_construct_params["site_super_users_attributes"]
    @site_construct.update_attributes(site_construct_params)
    @site_construct.check_super_user_changed
    if removed_super_users.count != 0
      @site_construct.removed_super_users += removed_super_users
      @site_construct.super_user_changed = true
      @site_construct.save
    end
    redirect_back_custom
  end
  def redirect_back_custom
    if Is_Rails5
      redirect_back(fallback_location: { action: "setting"})
    else
      redirect_to :back
    end
  end
  def setting
    ClientManagerSetting.create if ClientManagerSetting.count == 0
    @setting = ClientManagerSetting.first
  end
  def update_setting
    setting_params = params.require(:client_manager_setting).permit!
    setting = ClientManagerSetting.first
    setting.update_attributes(setting_params)
    redirect_back_custom
  end
  def upload_cert
    @site_cert = SiteCert.new
  end
  def edit_cert
    @site_cert = SiteCert.find(params[:site_panel_id])
  end
  def update_cert
    @site_cert = SiteCert.find(params[:site_panel_id])
    @site_cert.update_attributes(site_cert_params)
    redirect_to cert_management_admin_site_panel_index_path
  end
  def create_cert
    @site_cert = SiteCert.create(site_cert_params)
    redirect_to cert_management_admin_site_panel_index_path
  end
  def destroy_cert
    @site_cert = SiteCert.find(params[:site_panel_id])
    @site_cert.destroy
    redirect_to cert_management_admin_site_panel_index_path
  end
  def get_certs_for_site
    site_construct = SiteConstruct.find(params[:id]) rescue nil
    @site_construct = site_construct
    domain_name = site_construct.domain_name rescue ""
    domain_names = domain_name.split(" ").select{|s| s.present?}
    domain_names_count = domain_names.count
    (0...domain_names_count).each do |i|
      domain_names << domain_names[i].sub(/[^\.]+\./,'\\*.')
    end
    if domain_names.count != 0
      domain_name_search_text = "(" + domain_names.join("|") + ")"
    else
      domain_name_search_text = ""
    end
    @site_certs = SiteCert.all.where(:is_valid=>true,:domain_names=>/\A#{domain_name_search_text}/,:start_date.lte=>DateTime.now,:end_date.gte=>DateTime.now)
    # @site_certs = SiteCert.all
    if site_construct
      @enable_cert_id = site_construct.site_cert_id
    end
    render :layout => false
  end
  def cert_management
    @site_certs = SiteCert.all.order_by(id: :desc).page(params[:page]).per(10)
    @filter_fields = {}
    params[:keywords] = params[:keywords].to_s.gsub("*","\\*")
    @site_certs = search_data(@site_certs,[:domain_names])
    if request.xhr?
      render :partial => "certs_table"
    end
  end
  def update_cert_setting
    site_params = params.require('site').permit!
    if !site_params['cert_ver_file_content'].blank?
      site_params['cert_ver_file_content'] = Nokogiri::HTML.parse(site_params['cert_ver_file_content'].gsub(/\r\n|\n/,'').gsub(/<br[ \/]*>/, "\n")).inner_text
    end
    if !site_params['cert_ver_location_path'].blank? && site_params['cert_ver_location_path'].start_with?('h')
      site_params['cert_ver_location_path'] = URI(site_params['cert_ver_location_path']).path
    end
    site = SiteConstruct.where(id: site_params[:id]).first
    site.update_attributes(site_params)
    Thread.new do
      system("bundle exec rake create_site:add_cert_ver_for_site['#{site_params[:id]}']")
    end
    redirect_to "/#{I18n.locale}/admin/site_panel/sites_list?server_name=#{site.server_type}"
  end
  
  def index
    @site_construct = SiteConstruct.new
    @module_app = ModuleApp.where(:title=>@app_title).first
  end
  def server_manager
    @module_app = ModuleApp.where(:title=>@app_title).first
    @categories = @module_app.categories
    @tags = []
    @filter_fields = filter_fields(@categories,@tags)
    @site_servers = SiteServer.all.with_categories(filters("category")).with_status(filters("status"))
    @site_servers = search_data(@site_servers,[:server_name,:ip]).page(params[:page].to_i).per(10)
    if request.xhr?
      render :partial => "server_manager_index"
    end
  end
  def edit_server_info
    @module_app = ModuleApp.where(:title=>@app_title).first
    if params[:type] == 'update'
      @site_server = SiteServer.find(params[:id]) rescue nil
      if @site_server.present?
        @site_server.update_attributes(site_server_params)
      else
        @site_server = SiteServer.create(site_server_params)
      end
      redirect_to admin_site_panel_server_manager_path
    elsif params[:type] == 'create'
      @site_server = SiteServer.new
    elsif params[:type] == 'delete'
      SiteServer.find(params[:id]).destroy
      redirect_to admin_site_panel_server_manager_path
    elsif params[:type] == 'detect_sites'
      extra_text = ""
      if params[:key].present?
        extra_text = "['#{params[:key].gsub(/[\(\)\[\]]/){|ff| "\\"+ff }}']"
      end
      Thread.new do
        system("bundle exec rake create_site:detect_sites#{extra_text}")
      end
      render :json => {"success"=>true}
    elsif params[:type] == 'see_infos'
      if params["key"].blank?
        thread = Multithread.where(:key=>'detect_sites').first
        if thread.nil?
          thread = Multithread.where(:key=>'execing_commands').first
        else
          if thread.status["status"] == "finish" || thread.status["status"] == "error"
            exec_thread = Multithread.where(:key=>'execing_commands').first
            thread = exec_thread if !exec_thread.nil?
          end
        end
      else
        thread = Multithread.where(:key=>params["key"]).first
      end
      if thread.nil?
        render :json => {"infos"=>[],"status"=>"starting"}
      else
        render :json => thread.status
      end
    elsif params[:type] == 'get_server_names'
      render :json => (SiteServer.all.where(:active=>true).map{|s| s.server_name rescue ""}.select{|n| !n.blank?} rescue [])
    else
      @site_server = SiteServer.find(params[:id])
    end
  end
  def update_nginx_settings
    extra_text = ""
    if params[:key].present?
      extra_text = "[#{params[:key].gsub(/[\(\)\[\]]/){|ff| "\\"+ff }}]"
    end
    Thread.new do
      system("bundle exec rake create_site:update_multiple_nginx_setting#{extra_text}")
    end
    render :json => {"success"=>true}
  end
  def install_certbot
    extra_text = ""
    if params[:server_name].present?
      extra_text = "['#{params[:server_name].gsub(/[\(\)\[\]]/){|ff| "\\"+ff }}']"
    end
    Thread.new do
      system("bundle exec rake create_site:install_certbot#{extra_text}")
    end
    render :json => {"success"=>true}
  end
  def create
    server_ability = ServerAbility.first
    if server_ability.available
      site_construct = SiteConstruct.new(site_construct_params)
      site_construct.user_id = current_user.id.to_s
      site_construct.status = "creating"
      site_construct.save
      check_server_ability(1)
      git_url = "https://ruling.digital/git"#"http://gitlab.tp.rulingcom.com/orbit_chiu1/orbit4-5.git"
      git_template_url = "http://gitlab.tp.rulingcom.com/themes/default-theme.git"
      git_extension_url = "http://gitlab.tp.rulingcom.com/core/default-modules.git"
      site_server = SiteServer.where(:server_name=>site_construct.server_type).first
      ip = site_server.ip
      server_port = site_server.port
      user = site_server.account
      password = site_server.password
      site_name = site_construct.site_name
      domain_name = site_construct.domain_name
      port = site_construct.get_port
      db_name = site_construct.db_name
      path = site_construct.path
      site_construct_id = site_construct.id.to_s
      if site_construct.copy_id.blank?
        Thread.new do
          system("bundle exec rake create_site:create_site['#{git_template_url}','#{git_extension_url}','#{git_url}','#{ip}','#{server_port}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}']")
        end
      else
        Thread.new do
          system("bundle exec rake create_site:copy_site['#{ip}','#{server_port}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}','#{site_construct.copy_id}',#{site_construct.only_copy_installed_module}]")
        end
      end
      redirect_to "#{admin_site_panel_sites_list_path}?id=#{site_construct_id}"
    else
      render :text => I18n.t('client_management.over_the_limit')
    end
  end
  def create_site
    site_construct = SiteConstruct.find(params[:id])
    site_construct.user_id = current_user.id.to_s
    git_url = "https://ruling.digital/git"#"http://gitlab.tp.rulingcom.com/orbit_chiu1/orbit4-5.git"
    git_template_url = "http://gitlab.tp.rulingcom.com/themes/default-theme.git"
    git_extension_url = "http://gitlab.tp.rulingcom.com/core/default-modules.git"
    site_server = SiteServer.where(:server_name=>site_construct.server_type).first
    ip = site_server.ip
    server_port = site_server.port
    user = site_server.account
    password = site_server.password
    site_name = site_construct.site_name
    domain_name = site_construct.domain_name
    port = site_construct.get_port
    db_name = site_construct.db_name
    path = site_construct.path
    site_construct_id = params[:id]
    if site_construct.copy_id
      Thread.new do
        system("bundle exec rake create_site:copy_site['#{ip}','#{server_port}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}','#{site_construct.copy_id}',#{site_construct.only_copy_installed_module}]")
      end
    else
      Thread.new do
        system("bundle exec rake create_site:create_site['#{git_template_url}','#{git_extension_url}','#{git_url}','#{ip}','#{server_port}','#{user}','#{password}','#{site_name}','#{domain_name}','#{port}','#{db_name}','#{path}','#{site_construct_id}']")
      end
    end
    render :json =>{"success"=>true}
  end
  def edit_site
    case params[:type]
    when 'delete'
      Thread.new do
        system("bundle exec rake create_site:delete_site[#{params[:id]}]")
      end
    when 'close'
      Thread.new do
        Rake::Task['exec_commands:exec_commands'].execute(Rake::TaskArguments.new([:site_construct_id,:commands,:type], [params[:id], '', 'close_site']))
      end
    when 'open', 'restart'
      Thread.new do
        Rake::Task['exec_commands:exec_commands'].execute(Rake::TaskArguments.new([:site_construct_id,:commands,:type,:server_name,:rails_env], [params[:id], '', 'open_site', '', params[:env]]))
      end
    when 'detail'
      @site_construct = SiteConstruct.find(params[:id])
      render 'see_detail_for_created_site' and return
    when 'change_server_name'
      site_construct = SiteConstruct.find(params[:id])
      site_construct.update_attributes(update_site_params)
      site_construct.update(:domain_name=>params[:site_construct][:domain_name])
      cmd = "bundle exec rake create_site:change_site_server_name[#{params[:id]},'#{params[:site_construct][:domain_name]}','#{params[:site_construct][:port].to_a.join('////') }']"
      site_construct.update(:status=>"execing",:infos=>["Execing change domain name task..."])
      Thread.new do
        Bundler.with_clean_env{system(cmd)}
      end
      redirect_to admin_site_panel_edit_site_path(:id=>params[:id],:type=>'detail',:status=>'changing') and return
    when 'delete_from_list'
      SiteConstruct.find(params[:id]).destroy
      if Is_Rails5
        redirect_back(fallback_location: { action: "sites_list"})
      else
        redirect_to :back and return
      end
    when 'select_cert'
      is_certbot = true
      if params[:server_names]
        is_certbot = false
        Thread.new do
          last_idx = params[:server_names].count
          params[:server_names].each_with_index do |server_name, i|
            ss = SiteServer.where(:server_name=>server_name).first
            next if ss.nil?
            system("bundle exec rake create_site:change_site_cert[#{ss.id.to_s},#{is_certbot},true,#{params[:site_cert_id]},#{params[:redirect_to_https]}#{i == (last_idx -1) ? ',true' : ''}}]")
          end
        end
      else
        if !params[:is_server]
          @site_construct = SiteConstruct.find(params[:id])
          @site_construct.update(:redirect_to_https=>params[:redirect_to_https])
          if params[:site_cert_id] != "certbot"
            is_certbot = false
            @site_construct.update(:site_cert_id=>BSON::ObjectId(params[:site_cert_id]))
          end
        else
          is_certbot = true
        end
        Thread.new do
          system("bundle exec rake create_site:change_site_cert[#{params[:id]},#{is_certbot},#{params[:is_server]}]")
        end
      end
    when 'apply_change_users'
      Thread.new do
        exec_commands_args = {}
        site_server = nil
        site_construct = nil
        if params[:is_server] == 'true'
          site_server = SiteServer.find(params[:id])
          site_super_users = site_server.site_super_users.where(:is_changed=>true).to_a
          removed_super_users = site_server.removed_super_users
          exec_commands_args = {:type=>'exec_all', :server_name=>site_server.server_name}
          clean_thread_execing_info
        else
          site_construct = SiteConstruct.find(params[:id])
          site_super_users = site_construct.site_super_users.where(:is_changed=>true).to_a
          removed_super_users = site_construct.removed_super_users
          exec_commands_args = {:site_construct_id=>params[:id], :type=>'exec_commands'}
        end
        commands = []
        commands_i18n = []
        removed_super_users.uniq.each do |user_name|
          commands << remove_user_mongo_eval_cmd(user_name)
          commands_i18n << "Delete Super Manager: #{user_name}"
        end
        site_super_users.each do |super_user|
          user_attrs = super_user.get_attrs
          old_user_name = super_user.old_user_name
          member_profile = MemberProfile.new(id: nil, is_hidden: true, position: 0)
          member_profile.send(:generate_uid)
          member_attrs = member_profile.attributes
          member_attrs.delete('_id')
          commands << user_mongo_eval_cmd(user_attrs, member_attrs, (old_user_name.blank? ? nil : old_user_name))
          if old_user_name == ''
            commands_i18n << "Create Super Manager: #{super_user.user_name}"
          else
            commands_i18n << "Update Super Manager: #{super_user.user_name}"
          end
        end
        if commands.count > 0
          site_construct.update(:status=>"execing",:infos=>[""]) if site_construct
          exec_commands_args[:commands] = commands
          exec_commands_args[:commands_i18n] = commands_i18n
          if system("bundle exec rake exec_commands:exec_commands[\"#{Base64.strict_encode64(exec_commands_args.to_json)}\"]")
            SiteSuperUser.where(:id.in=>site_super_users.map{|u| u.id}).clear_changed
            if site_server
              site_server.update(:super_user_changed => false, :removed_super_users => [])
            end
            if site_construct
              site_construct.update(:super_user_changed => false, :removed_super_users => [])
            end
          end
        end
      end
    when 'apply_change_backup_setting'
      Thread.new do
        system("bundle exec rake exec_commands:change_backup_setting[#{params[:id]}]")
      end
    else
      Thread.new do
        cmds = params[:commands].split('////')
        commands_i18n = (0...cmds.count).collect{nil}
        if cmds.include?('{{create_super_manager}}') && !params[:account].blank? && !params[:password].blank?
          site_server_ids = []
          site_construct_id = nil
          if params[:id].blank? && !params[:server_names].blank?
            site_server_ids = SiteServer.where(:server_name.in=>params[:server_names]).pluck(:id)
          else
            site_construct = SiteConstruct.find(params[:id])
            site_construct.update(:status=>"execing",:infos=>[""])
            site_construct_id = site_construct.id rescue nil
          end
          idx = cmds.index('{{create_super_manager}}')
          cmds[idx] = create_super_manager_cmd(params[:account],params[:password], site_server_ids, site_construct_id)
          commands_i18n[idx] = "#{@create_super_user ? 'Create' : 'Update'} Super Manager: #{params[:account]}"
        end
        if commands_i18n.compact.count == 0
          commands_i18n = nil
        end
        exec_commands_args = {}
        if params[:id].blank? && !params[:server_names].blank?
          exec_commands_args = {:commands=>cmds.join('////'), :type=>'exec_all', :server_name=>params[:server_names].join('////')}
          clean_thread_execing_info
        else
          exec_commands_args = {:site_construct_id=>params[:id], :commands=>cmds.join('////'), :type=>'exec_commands'}
        end
        exec_commands_args[:commands_i18n] = commands_i18n
        system("bundle exec rake exec_commands:exec_commands[\"#{Base64.strict_encode64(exec_commands_args.to_json)}\"]")
      end
    end
    render :json =>{"success"=>true}
  end
  def clean_thread_execing_info
    Multithread.where(:key=>'execing_commands').each do |thread|
      if thread.status["status"] == "error" || thread.status["status"] == "finish"
        thread.destroy
      elsif thread.updated_at < (Time.now - 5.minute)
        thread.destroy
      end
    end
  end
  def sites_list
    @module_app = ModuleApp.where(:title=>@app_title).first
    @categories = @module_app.categories
    @filter_fields = filter_fields(@categories, [])
    site_modes = ["development","production"]
    @filter_fields["client_management.site_mode"] = site_modes.map{|mode| {:title=>I18n.t("client_management.#{mode}"), :id=>mode}}
    @sites = SiteConstruct.any_in(:hidden=>[false,nil]).desc(:id)
    @site_servers = SiteServer.all.with_categories(filters("category"))
    @sites = (params[:server_name].blank? ? @sites : @sites.where(:server_type=>params[:server_name]))
    @sites = @sites.any_in(:server_type => @site_servers.map{|s| s.server_name})
    @sites = search_data(@sites,[:domain_name,:site_name,:school_name,:status,:port]).page(params[:page].to_i).per(10)
    if (params[:filters][:site_mode].present? rescue false)
      site_modes = params[:filters][:site_mode]
      if site_modes.include?("development")
        site_modes << nil
      end
      @sites = @sites.where(:rails_env.in=>site_modes,:status=>"finish")
    end
    if request.xhr?
      render :partial => "sites_list_table"
    end
  end
  def site_infos
    site_construct = SiteConstruct.where(:id=>params[:id]).first
    if site_construct.nil?
      render :json => {:status=>"creating",:infos=>[]}
    else
      render :json => {:status=>site_construct.status,:infos=>site_construct.infos}
    end
  end
  def backup_setting
    @site_server = SiteServer.find(params[:id])
  end
  def update_backup_setting
    @site_server = SiteServer.find(params[:id])
    site_server_params = params.require(:site_server).permit! rescue {}
    need_rewrite_backup_setting = false
    site_server_params["site_server_file_backups_attributes"].each do |k, v|
      if v["_destroy"] == 'true'
        need_rewrite_backup_setting = true
      end
    end if site_server_params["site_server_file_backups_attributes"]
    site_server_params["site_server_db_backups_attributes"].each do |k, v|
      if v["_destroy"] == 'true'
        need_rewrite_backup_setting = true
      end
    end if site_server_params["site_server_db_backups_attributes"]
    @site_server.update_attributes(site_server_params)
    unless need_rewrite_backup_setting
      need_rewrite_backup_setting = ((@site_server.site_server_file_backups.where(:need_rewrite=>true).count + @site_server.site_server_db_backups.where(:need_rewrite=>true).count) != 0)
    end
    if need_rewrite_backup_setting
      @site_server.update(:need_rewrite_backup_setting=>true)
    end
    redirect_back_custom
  end
  private
  def site_cert_params
    site_cert_params = params.require(:site_cert).permit! rescue {}
  end
  def site_construct_params
    site_construct_params = params.require(:site_construct).permit! rescue {}
  end
  def site_server_params
    server_params = params.require(:site_server).permit! rescue {}
    if server_params[:default_domain_names].nil?
      server_params[:default_domain_names] = []
    end
    server_params
  end
  def check_server_ability(site_num_add=0)
    store_token = current_site.store_token
    network = ONetwork.new(OrbitStore::URL,"post")
    site_num = SiteConstruct.where(:hidden.ne=> true,:status => 'finish',:server_type.in => SiteServer.all.collect(&:server_name)).count + site_num_add
    response = network.request("/xhr/check_server_ability",
                              {"store_token" => store_token,
                               "site_num" => site_num,
                               "site_name" => current_site.title,
                               "site_url" => current_site.root_url})
    data = JSON.parse(response.body) rescue {}
    @server_ability = ServerAbility.first
    if data.keys.length>0 && !data['ability'].blank?
      @server_ability.update_attributes(ability: data['ability'], site_num: site_num)
    else
      @server_ability.update_attributes(site_num: site_num)
    end
  end
  def update_site_params
    site_params = params.require(:site_construct).permit!
    site_params.except(:domain_name,:port)
  end
  def create_super_manager_cmd(user_name, password, site_server_ids, site_construct_id)
    password_digest = SiteSuperUser.generate_password_digest(password)
    user_attrs = nil
    super_user = nil
    if site_server_ids.present?
      site_server_ids.each_with_index do |site_server_id, i|
        super_user = SiteSuperUser.where(:site_server_id=>site_server_id, :user_name=>user_name).first
        if super_user.nil?
          super_user = SiteSuperUser.new(:site_server_id=>site_server_id, :user_name=>user_name)
          @create_super_user = true
        end
        super_user.update_password_digest(password_digest)
        if i == 0
          user_attrs = super_user.get_attrs
        end
      end
    elsif site_construct_id.present?
      super_user = SiteSuperUser.where(:site_construct_id=>site_construct_id, :user_name=>user_name).first
      if super_user.nil?
        super_user = SiteSuperUser.new(:site_construct_id=>site_construct_id, :user_name=>user_name)
        @create_super_user = true
      end
      super_user.update_password_digest(password_digest)
      user_attrs = super_user.get_attrs
    end
    member_profile = MemberProfile.new(id: nil, is_hidden: true, position: 0)
    member_profile.send(:generate_uid)
    member_attrs = member_profile.attributes
    member_attrs.delete('_id')
    user_mongo_eval_cmd(user_attrs, member_attrs)
  end
  def remove_user_mongo_eval_cmd(user_name)
    cmd = """mongo --eval 'a=function(){
    var user_query = {user_name: \"#{user_name}\"};
    user = db.users.findOne(user_query);
    if (user) {
      var bulk = db.member_profiles.initializeUnorderedBulkOp();
      bulk.find({_id: user[\"member_profile_id\"]}).removeOne();
      bulk.execute();
      var bulk = db.users.initializeUnorderedBulkOp();
      bulk.find(user_query).removeOne();
      bulk.execute();
    }
    }()' {{db_name}}""".gsub(/\n|^ */,"")
  end
  def user_mongo_eval_cmd(user_attrs, member_attrs, old_user_name=nil)
    cmd = """mongo --eval 'a=function(){
    var user_query = {user_name: \"#{old_user_name ? old_user_name : user_attrs['user_name']}\"};
    var user = db.users.findOne(user_query);
    var user_id;
    var user_data = #{user_attrs.to_json};
    var time = new Date();
    user_data.created_at = time;
    user_data.updated_at = time;
    user_data.password_updated_at = time;
    if (user){
      user_data._id  = user._id;
      db.users.update(user_query, {$set: user_data});
    }else{
      var bulk = db.users.initializeUnorderedBulkOp();
      bulk.insert(user_data);
      bulk.execute();
    }
    user_query = {user_name: \"#{user_attrs['user_name']}\"};
    user = db.users.findOne(user_query);
    var member_query = {_id: user.member_profile_id};
    if (member_query[\"_id\"] == null){
      member_query[\"_id\"] = null;
    }
    var member = user.member_profile_id ? db.member_profiles.findOne(member_query) : null;
    var member_data = #{member_attrs.to_json};
    member_data.created_at = time;
    member_data.updated_at = time;
    if (member){
      delete member_data[\"uid\"];
      member = db.member_profiles.update(member_query, {$set: member_data});
    }else{
      var bulk = db.member_profiles.initializeUnorderedBulkOp();
      bulk.insert(member_data);
      bulk.execute();
      user_data.member_profile_id = bulk.getOperations()[0][\"operations\"][0][\"_id\"];
      db.users.update(user_query, {$set: user_data});
    }
    }()' {{db_name}}""".gsub(/\n|^ */,"")
  end
end