
@suitecrm_tables = (
	"accounts",
	"accounts_audit",
	"accounts_bugs",
	"accounts_cases",
	"accounts_contacts",
	"accounts_opportunities",
	"acl_actions",
	"acl_roles",
	"acl_roles_actions",
	"acl_roles_users",
	"bugs",
	"bugs_audit",
	"calls",
	"calls_contacts",
	"calls_users",
	"calls_leads",
	"campaign_log",
	"campaign_trkrs",
	"campaigns",
	"campaigns_audit",
	"cases",
	"cases_audit",
	"cases_bugs",
	"config",
	"contacts",
	"contacts_audit",
	"contacts_bugs",
	"contacts_cases",
	"contacts_users",
	"cron_remove_documents",
	"currencies",
	"custom_fields",
	"dashboards",
	"document_revisions",
	"documents",
	"documents_accounts",
	"documents_bugs",
	"documents_cases",
	"documents_contacts",
	"documents_opportunities",
	"eapm",
	"eapm_audit",
	"email_marketing",
	"email_marketing_prospect_lists",
	"email_templates",
	"emailman",
	"emails",
	"emails_accounts",
	"emails_bugs",
	"emails_cases",
	"emails_contacts",
	"emails_leads",
	"emails_opportunities",
	"emails_project_tasks",
	"emails_projects",
	"emails_prospects",
	"emails_tasks",
	"emails_users",
	"feeds",
	"fields_meta_data",
	"files",
	"iframes",
	"import_maps",
	"inbound_email",
	"inbound_email_autoreply",
	"job_queue",
	"leads",
	"leads_audit",
	"linked_documents",
	"meetings",
	"meetings_contacts",
	"meetings_users",
	"meetings_leads",
	"notes",
	"oauth_consumer",
	"oauth_nonce",
	"oauth_tokens",
	"opportunities",
	"opportunities_audit",
	"opportunities_contacts",
	"project",
	"project_relation",
	"project_task",
	"project_task_audit",
	"prospect_list_campaigns",
	"prospect_lists",
	"prospect_lists_prospects",
	"prospects",
	"relationships",
	"releases",
	"roles",
	"roles_modules",
	"roles_users",
	"saved_search",
	"schedulers",
	"schedulers_times",
	"sugarfeed",
	"tasks",
	"tracker",
	"upgrade_history",
	"user_preferences",
	"users",
	"users_feeds",
	"users_last_import",
	"users_password_link",
	"users_signatures",
	"vcals",
	"versions",
	"address_book",
	"email_addr_bean_rel",
	"email_addresses",
	"email_cache",
	"emails_beans",
	"emails_email_addr_rel",
	"emails_text",
	"folders",
	"folders_rel",
	"folders_subscriptions",
	"inbound_email_cache_ts",
	"outbound_email",
	"projects_accounts",
	"projects_bugs",
	"projects_cases",
	"projects_contacts",
	"projects_opportunities",
	"projects_products",
	"accounts_cstm",
	"alerts",
	"am_projecttemplates",
	"am_projecttemplates_audit",
	"am_projecttemplates_contacts_1_c",
	"am_projecttemplates_project_1_c",
	"am_projecttemplates_users_1_c",
	"am_tasktemplates",
	"am_tasktemplates_am_projecttemplates_c",
	"am_tasktemplates_audit",
	"aobh_businesshours",
	"aod_index",
	"aod_index_audit",
	"aod_indexevent",
	"aod_indexevent_audit",
	"aok_knowledge_base_categories",
	"aok_knowledge_base_categories_audit",
	"aok_knowledgebase",
	"aok_knowledgebase_audit",
	"aok_knowledgebase_categories",
	"aop_case_events",
	"aop_case_events_audit",
	"aop_case_updates",
	"aop_case_updates_audit",
	"aor_charts",
	"aor_conditions",
	"aor_fields",
	"aor_reports",
	"aor_reports_audit",
	"aor_scheduled_reports",
	"aos_contracts",
	"aos_contracts_audit",
	"aos_contracts_documents",
	"aos_invoices",
	"aos_invoices_audit",
	"aos_line_item_groups",
	"aos_line_item_groups_audit",
	"aos_pdf_templates",
	"aos_pdf_templates_audit",
	"aos_product_categories",
	"aos_product_categories_audit",
	"aos_products",
	"aos_products_audit",
	"aos_products_quotes",
	"aos_products_quotes_audit",
	"aos_quotes",
	"aos_quotes_aos_invoices_c",
	"aos_quotes_audit",
	"aos_quotes_os_contracts_c",
	"aos_quotes_project_c",
	"aow_actions",
	"aow_conditions",
	"aow_processed",
	"aow_processed_aow_actions",
	"aow_workflow",
	"aow_workflow_audit",
	"calls_reschedule",
	"calls_reschedule_audit",
	"cases_cstm",
	"contacts_cstm",
	"favorites",
	"fp_event_locations",
	"fp_event_locations_audit",
	"fp_event_locations_fp_events_1_c",
	"fp_events",
	"fp_events_audit",
	"fp_events_contacts_c",
	"fp_events_fp_event_delegates_1_c",
	"fp_events_fp_event_locations_1_c",
	"fp_events_leads_1_c",
	"fp_events_prospects_1_c",
	"jjwg_address_cache",
	"jjwg_address_cache_audit",
	"jjwg_areas",
	"jjwg_areas_audit",
	"jjwg_maps",
	"jjwg_maps_audit",
	"jjwg_maps_jjwg_areas_c",
	"jjwg_maps_jjwg_markers_c",
	"jjwg_markers",
	"jjwg_markers_audit",
	"leads_cstm",
	"meetings_cstm",
	"opportunities_cstm",
	"outbound_email_audit",
	"project_contacts_1_c",
	"project_cstm",
	"project_users_1_c",
	"prospects_cstm",
	"reminders",
	"reminders_invitees",
	"securitygroups",
	"securitygroups_acl_roles",
	"securitygroups_audit",
	"securitygroups_default",
	"securitygroups_records",
	"securitygroups_users",
	"spots",
	"templatesectionline",
	);

# script_suitecrm_desc()
sub script_suitecrm_desc
{
return "SuiteCRM";
}

sub script_suitecrm_uses
{
return ( "php" );
}

sub script_suitecrm_longdesc
{
return "A powerful open-source package for managing customer relationships";
}

# script_suitecrm_versions()
sub script_suitecrm_versions
{
return ( "8.2.3", "7.12.6" );
}

sub script_suitecrm_can_upgrade
{
local ($sinfo, $newver) = @_;
if ($newver >= 5.5 && $sinfo->{'version'} < 5.5) {
	return 0;
	}
return 1;
}

sub script_suitecrm_category
{
return "Commerce";
}

sub script_suitecrm_php_vers
{
return ( 5 );
}

sub script_suitecrm_php_fullver
{
local ($d, $ver, $sinfo) = @_;
return &compare_versions($ver, 8) >= 0 ? 7.3 : 7.0;
}


sub script_suitecrm_php_modules
{
return ( "mysql", "curl", "zip", "xml",
         "json", "mbstring" );
}

sub script_suitecrm_php_optional_modules
{
return ( "imap", "gd" );
}

sub script_suitecrm_dbs
{
return ("mysql");
}

# script_suitecrm_php_vars(&domain)
# Returns an array of extra PHP variables needed for this script
sub script_suitecrm_php_vars
{
return ( [ 'safe_mode', 'Off' ],
	 [ 'memory_limit', '128M', '+' ],
	 [ 'upload_max_filesize', '64M', '+' ],
	 [ 'max_execution_time', '120', '+' ] );
}

# script_suitecrm_params(&domain, version, &upgrade-info)
# Returns HTML for table rows for options for installing SuiteCRM
sub script_suitecrm_params
{
local ($d, $ver, $upgrade) = @_;
local $rv;
local $hdir = &public_html_dir($d, 1);
if ($upgrade) {
	# Options are fixed when upgrading
	local ($dbtype, $dbname) = split(/_/, $upgrade->{'opts'}->{'db'}, 2);
	$rv .= &ui_table_row("Database for SuiteCRM tables", $dbname);
	local $dir = $upgrade->{'opts'}->{'dir'};
	$dir =~ s/^$d->{'home'}\///;
	$rv .= &ui_table_row("Install directory", $dir);
	}
else {
	# Show editable install options
	local @dbs = &domain_databases($d, [ "mysql" ]);
	$rv .= &ui_table_row("Database for SuiteCRM tables",
		     &ui_database_select("db", undef, \@dbs, $d, "suitecrm"));
	$rv .= &ui_table_row("Install sub-directory under <tt>$hdir</tt>",
			     &ui_opt_textbox("dir", &substitute_scriptname_template("suitecrm", $d), 30, "At top level"));
	$rv .= &ui_table_row("Install demo data?",
			     &ui_yesno_radio("demo", 1));
	}
return $rv;
}

# script_suitecrm_parse(&domain, version, &in, &upgrade-info)
# Returns either a hash ref of parsed options, or an error string
sub script_suitecrm_parse
{
local ($d, $ver, $in, $upgrade) = @_;
if ($upgrade) {
	# Options are always the same
	return $upgrade->{'opts'};
	}
else {
	local $hdir = &public_html_dir($d, 0);
	$in{'dir_def'} || $in{'dir'} =~ /\S/ && $in{'dir'} !~ /\.\./ ||
		return "Missing or invalid installation directory";
	local $dir = $in{'dir_def'} ? $hdir : "$hdir/$in{'dir'}";
	local ($newdb) = ($in->{'db'} =~ s/^\*//);
	return { 'db' => $in->{'db'},
		 'newdb' => $newdb,
	 	 'demo' => $in->{'demo'},
	         'dir' => $dir,
		 'path' => $in{'dir_def'} ? "/" : "/$in{'dir'}", };
	}
}

# script_suitecrm_check(&domain, version, &opts, &upgrade-info)
# Returns an error message if a required option is missing or invalid
sub script_suitecrm_check
{
local ($d, $ver, $opts, $upgrade) = @_;
$opts->{'dir'} =~ /^\// || return "Missing or invalid install directory";
$opts->{'db'} || return "Missing database";
if (-r "$opts->{'dir'}/install.php") {
	return "SuiteCRM appears to be already installed in the selected directory";
	}
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
foreach my $t (@suitecrm_tables) {
	local $clash = &find_database_table($dbtype, $dbname, $t);
	$clash && return "SuiteCRM appears to be already using the selected database (table $clash)";
	}
$opts->{'demo'} = 1 if (!defined($opts->{'demo'}));
return undef;
}

# script_suitecrm_files(&domain, version, &opts, &upgrade-info)
# Returns a list of files needed by SuiteCRM, each of which is a hash ref
# containing a name, filename and URL
sub script_suitecrm_files
{
local ($d, $ver, $opts, $upgrade) = @_;
local $basever = $ver;
$basever =~ s/\.(\d+)$/\.X/;
local @files = ( { 'name' => "source",
		   'file' => "SuiteCRM-$ver.zip",
		   'url' => "https://sourceforge.net/projects/suitecrm/files/SuiteCRM-$ver.zip" } );
return @files;
}

sub script_suitecrm_commands
{
return ("unzip", "wget");
}

# script_suitecrm_install(&domain, version, &opts, &files, &upgrade-info)
# Actually installs SuiteCRM, and returns either 1 and an informational
# message, or 0 and an error
sub script_suitecrm_install
{
local ($d, $version, $opts, $files, $upgrade, $domuser, $dompass) = @_;

local ($out, $ex);
if ($opts->{'newdb'} && !$upgrade) {
	local $err = &create_script_database($d, $opts->{'db'});
	return (0, "Database creation failed : $err") if ($err);
	}
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local $dbuser = $dbtype eq "mysql" ? &mysql_user($d) : &postgres_user($d);
local $dbpass = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
local $dbphptype = $dbtype eq "mysql" ? "mysql" : "psql";
local $dbhost = &get_database_host($dbtype, $d);
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
return (0, "Database connection failed : $dberr") if ($dberr);

# Preserve old config file
local $cfile = "$opts->{'dir'}/config.php";
local $oldcfile = &transname();
if ($upgrade) {
	&copy_source_dest($cfile, $oldcfile);
	}

# Extract tar file to temp dir and copy to target
local $temp = &transname();
local $err = &extract_script_archive($files->{'source'}, $temp, $d,
                                     $opts->{'dir'},
                                     $version >= 8 ? "" : "SuiteCRM-$ver");
$err && return (0, "Failed to extract source : $err");

my $prefix = $version >= 8 ? "public/legacy/" : "";
var_dump($prefix, 'prefix1');
# Make sub-directories writable
# my $ver8
foreach my $sd ("${prefix}cache", "${prefix}custom", "${prefix}data", "${prefix}modules") {
	&make_file_php_writable($d, "$opts->{'dir'}/$sd");
	}

local $url = &script_path_url($d, $opts);
if ($upgrade) {
	# Put back original config file
	&copy_source_dest_as_domain_user($d, $oldcfile, $cfile);
	}
else {
	# Make config.php writable
	&make_file_php_writable($d, $cfile);

	#goto SKIP;

	# Request the first page to get a cookie
	$suitecrm_session_cookie = undef;
	local ($out, $error);
	&get_http_connection($d, "$opts->{'path'}/${prefix}install.php",
			     \$out, \$error, \&suitecrm_cookie_callback);
	if ($error) {
		return (-1, "Failed to get session cookie : $error");
		}
	if (!$suitecrm_session_cookie) {
		return (-1, "No session cookie found");
		}
	print STDERR "cookie = $suitecrm_session_cookie\n";

	# First wizard page (language and licence check, returns system check
	# page)
	local @params = ( [ "language", "en_us" ] );
	local $err = &call_suitecrm_wizard_page(\@params, 0, $d, $opts, 0);
	return (-1, "SuiteCRM language wizard failed : $err") if ($err);

	# Second page (system check, returns DB form)
	local @params = ( );
	local $err = &call_suitecrm_wizard_page(\@params, 1, $d, $opts, 0);
	return (-1, "SuiteCRM check wizard failed : $err") if ($err);

	# Save config for DB connection and admin params
	local $surl = $url;
	$surl =~ s/\/$//;
	local @params = ( [ "setup_db_type", "mysql" ],
			  [ "setup_db_drop_tables", "" ],
			  [ "setup_db_database_name", $dbname ],
			  [ "setup_db_host_name", $dbhost ],
			  [ "setup_db_admin_user_name", $dbuser ],
			  [ "setup_db_admin_password_entry", $dbpass ],
			  [ "setup_db_admin_password", $dbpass ],
			  [ "setup_db_collation", 'utf8mb4_general_ci' ],
			  [ "setup_db_charset", 'utf8mb4' ],
			  [ "dbUSRData", "same" ],
			  [ "setup_db_sugarsales_user", $dbuser ],
			  [ "setup_db_sugarsales_password_entry", $dbpass ],
			  [ "setup_db_sugarsales_password", $dbpass ],
			  [ "setup_db_sugarsales_password_retype_entry", $dbpass ],
			  [ "setup_db_sugarsales_password_retype", $dbpass ],
			  [ "demoData", $opts->{'demo'} ? "yes" : "no" ],
			  [ "checkDBSettings", "true" ],
			  [ "setup_site_admin_user_name", "admin" ],
			  [ "setup_site_admin_password", $dompass ],
			  [ "setup_site_admin_password_retype", $dompass ],
			  [ "setup_site_url", $surl ],
			  [ "email1", $d->{'emailto'} ],
			  [ "scenarios[]", "Sales" ],
			  [ "scenarios[]", "Marketing" ],
			  [ "scenarios[]", "Finance" ],
			  [ "scenarios[]", "ServiceManagement" ],
			  [ "scenarios[]", "ProjectManagement" ],
			  [ "setup_system_name", "SuiteCRM" ],
			  [ "default_date_format", "m/d/Y" ],
			  [ "default_time_format", "h:ia" ],
			  [ "timezone", "UTC" ],
			  [ "default_language", "en_us" ],
			  [ "default_currency_name", "US Dollars" ],
			  [ "default_currency_symbol", "\$" ],
			  [ "default_currency_iso4217", "USD" ],
			  [ "setup_site_session_path", "" ],
			  [ "setup_site_log_dir", "." ],
			  [ "setup_site_guid", "" ],
			  [ "setup_db_drop_tables", "" ],
			  [ "smtp_tab_selected", "smtp_tab_other" ],
			  [ "smtp_tab_other[mail_smtpserver]", "localhost" ],
			  [ "smtp_tab_other[mail_smtpport]", 25 ],
			  [ "smtp_tab_other[mail_smtpauth_req]", 0 ],
			  [ "smtp_tab_other[mail_smtpssl]", "" ],
			  [ "smtp_tab_other[mail_smtpuser]", "" ],
			  [ "smtp_tab_other[mail_smtppass]", "" ],
			  [ "smtp_tab_other[notify_allow_default_outbound]", 0 ],
			 );
	local $err = &call_suitecrm_wizard_page(\@params, 2, $d, $opts, 0,
				"sugar_body_only=1&uploadLogoFrame=1&storeConfig=1&to_pdf=1&checkInstallSystem=true");
	return (-1, "SuiteCRM config store failed : $err") if ($err);

	# DB config check
	# XXX

	# Third page (Db connection and admin params, final save)
	local $err = &call_suitecrm_wizard_page(\@params, 2, $d, $opts, 1);
	return (-1, "SuiteCRM DB connection wizard failed : $err") if ($err);

	# Fix .htaccess again, as it gets created by the previous step
	sleep(5);
	&fix_script_htaccess_files($d, $opts->{'dir'});

	# Setup the Cron job
	&create_script_wget_job($d, $url."cron.php", '*', '*');

	# Allow referrers from Virtualmin
	# XXX ???
	my $host = $ENV{'HTTP_HOST'};
	$host =~ s/:\d+$//;
	$host ||= $d->{'dom'};
	&open_tempfile_as_domain_user($d, CONFIG,
		">$opts->{'dir'}/config_override.php");
	&print_tempfile(CONFIG, "<?php\n");
	&print_tempfile(CONFIG, "\$sugar_config['http_referer']['list'][] = '$host';\n");
	&print_tempfile(CONFIG, "?>\n");
	&close_tempfile(CONFIG);

	}

# Tell the user about the new install
local $rp = $opts->{'dir'};
$rp =~ s/^$d->{'home'}\///;
return (1, "Initial SuiteCRM installation complete. Go to <a target=_blank href='$url${prefix}'>$url</a> to complete the configuration process.", "Under $rp using $dbtype database $dbname", $url, 'admin', $dompass);
}

# call_suitecrm_wizard_page(&parameters, step-no, &domain, &opts,
# 			    mode[0=post, 1=form-data, 2=get], cgi-params)
sub call_suitecrm_wizard_page
{
local ($params, $step, $d, $opts, $formdata, $cgiparams) = @_;
my $prefix = $ver >= 8 ? "public/legacy/" : "";
local $params = join("&", map { $_->[0]."=".&urlize($_->[1]) }
			  ( @$params,
			    [ "current_step", $step ],
			    [ "goto", "Next" ] ));
local $ipage = $opts->{'path'}."/${prefix}install.php".
	       ($cgiparams ? "?".$cgiparams : "");

local ($iout, $ierror);
local (%headers, %gotheaders);
if ($suitecrm_session_cookie) {
	$headers{'Cookie'} = $suitecrm_session_cookie;
	}
if ($formdata == 2) {
	# Get request
	&get_http_connection($d, $ipage."?".$params, \$iout, \$ierror, undef,
			     0, undef, undef, 0, 0, 0, \%headers);
	}
else {
	# Post request, possibly form-data
	&post_http_connection($d, $ipage, $params, \$iout, \$ierror, \%headers,
			      \%gotheaders, undef, $formdata);
	}
if ($ierror) {
	return $ierror;
	}
print STDERR "-----------------------------------------\n";
print STDERR $iout;
print STDERR "-----------------------------------------\n";

# This call may have create a .htaccess file with bad permissions .. fix it
&set_permissions_as_domain_user($d, 0755, "$opts->{'dir'}/.htacces");

return undef;
}

# script_suitecrm_uninstall(&domain, version, &opts)
# Un-installs a SuiteCRM installation, by removing it's files
# Returns 1 on success and a message, or 0 on failure and an error
sub script_suitecrm_uninstall
{
local ($d, $version, $opts) = @_;

# Remove suitecrm tables from the database
&cleanup_script_database($d, $opts->{'db'}, \@suitecrm_tables);

# Remove the contents of the target directory
local $derr = &delete_script_install_directory($d, $opts);
return (0, $derr) if ($derr);

# Take out the DB
if ($opts->{'newdb'}) {
	&delete_script_database($d, $opts->{'db'});
	}

# Find and remove the Cron job
&delete_script_wget_job($d, $sinfo->{'url'}."cron.php");

return (1, "Deleted SuiteCRM directory and tables.");
}

sub script_suitecrm_stop
{
local ($d, $sinfo) = @_;
&delete_script_wget_job($d, $sinfo->{'url'}."cron.php");
}

# script_suitecrm_latest(version)
sub script_suitecrm_latest
{
return ( "https://sourceforge.net/projects/suitecrm/files/",
	 "SuiteCRM-([0-9\\.]+)\\.zip" );
}

sub script_suitecrm_site
{
return 'http://www.suitecrm.com/';
}

sub script_suitecrm_passmode
{
return 2;
}

# script_suitecrm_realversion(&domain, &opts)
# Returns the real version number of some script install, or undef if unknown
sub script_suitecrm_realversion
{
local ($d, $opts, $sinfo) = @_;
local $lref = &read_file_lines("$opts->{'dir'}/sugar_version.php", 1);
foreach my $l (@$lref) {
	if ($l =~ /sugar_version\s*=\s*'([0-9A-Za-z\.]+)'/) {
		return $1;
		}
	}
return undef;
}

sub suitecrm_cookie_callback
{
if ($WebminCore::header{'set-cookie'} =~ /(PHPSESSID=[^ ;]+)/) {
	$suitecrm_session_cookie = $1;
	}
}



1;

