package Cpanel::Easy::Utils::MySQL;

# cpanel - Cpanel/Easy/Utils/MySQL.pm             Copyright(c) 2014 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited

use strict;
use warnings;
no warnings qw(redefine);
use Cpanel::FindBin         ();
use Cpanel::FileUtils::Path ();
use Cpanel::SafeRun::Errors ();

our @BASE_DIR = qw( /usr/local /usr );

sub get_system_mysql_info {
    my ( $self, $refresh ) = @_;
    local $_;
    my @ret;

    delete $self->{'cache'}{'get_system_mysql_info'} if $refresh;

    if ( exists $self->{'cache'}{'get_system_mysql_info'} && ref $self->{'cache'}{'get_system_mysql_info'} eq 'ARRAY' ) {
        return @{ $self->{'cache'}{'get_system_mysql_info'} };
    }

    # note: possible that mysql_config and mysql are in different base directories,
    #    but unlikely
    my @path = map { "$_/bin" } @BASE_DIR;
    my $config = Cpanel::FindBin::findbin( 'mysql_config', path => \@path, nocache => 1 );
    my $exe    = Cpanel::FindBin::findbin( 'mysql',        path => \@path, nocache => 1 );

    if ( $config && $exe ) {
        my $prefix = $config;
        $prefix =~ s{/bin/mysql_config}{};    # needed for applications that compile and want the "prefix"

        my $socket = Cpanel::SafeRun::Errors::saferunnoerror( $config, '--socket' ) || '';
        chomp $socket if $socket;
        my $version = Cpanel::SafeRun::Errors::saferunnoerror( $config, '--version' ) || '';
        chomp $version if $version;
        my $type = Cpanel::SafeRun::Errors::saferunnoerror( $exe, '--version' );
        $type = ( $type && $type =~ /mariadb/i ) ? 'mariadb' : 'mysql';

        @ret = ( $prefix, $config, $socket, $version, $type );
        $self->{'cache'}{'get_system_mysql_info'} = \@ret;
    }

    return @ret;
}

sub do_mysql_h_test_compile {
    my ( $self, $refresh ) = @_;

    $self->fix_missing_libmysqlclient();

    if ( !defined $refresh || !$refresh ) {
        if ( exists $self->{'cache'}{'get_system_mysql_info'} ) {
            if ( ref $self->{'cache'}{'do_mysql_h_test_compile'} eq 'ARRAY' ) {
                return @{ $self->{'cache'}{'do_mysql_h_test_compile'} };
            }
        }
    }
    else {
        delete $self->{'cache'}{'do_mysql_h_test_compile'};
    }

    my ( $prefix, $config, $socket, $version ) = $self->get_system_mysql_info();

    my $prog_src = '/cpmysql.c';
    my $prog     = '/cpmysql';
    my $c_code   = <<'MYSQL';
    #include <stdio.h>
    #include "mysql.h"
    
    main() {
        printf("cPanel Mysql test");
    }
MYSQL

    if ( open my $src_h, '>', $prog_src ) {
        print {$src_h} $c_code;
        close $src_h;
        my $gcc = qx{gcc `$config --cflags` `$config --libs` -o $prog $prog_src};

        my $test = `$prog`;

        foreach my $file ( $prog_src, $prog ) {
            Cpanel::FileUtils::safeunlink($file);
        }

        if ( $test eq 'cPanel Mysql test' ) {
            $self->{'cache'}{'do_mysql_h_test_compile'} = [ 1, 'Ok' ];
        }
        else {
            $self->{'cache'}{'do_mysql_h_test_compile'} = [ 0, "Could not compile a simple mysql.h program:\n\t-compile-\n[_1]\n\n\t-output-\n[_2]\n\n", $gcc, $test ];
        }

        return @{ $self->{'cache'}{'do_mysql_h_test_compile'} };
    }
    else {
        return ( 0, q{Could not open() file '[_1]' for writing: [_2]}, $prog_src, $! );
    }
}

sub fix_missing_libmysqlclient {

    # Nick's fix for certain broken Mysql installations where libmysqlclient.so of libmysqlclient_r.so is
    # installed in the wrong location and mysql-config or an old libtool archive file lists it incorrectly
    foreach my $libdir ( '/usr/lib/', '/usr/lib64/' ) {
        next unless -d $libdir . 'mysql';
        foreach my $mysqllibrary ( 'libmysqlclient.so', 'libmysqlclient_r.so' ) {
            symlink( '../' . $mysqllibrary, $libdir . 'mysql/' . $mysqllibrary ) if ( -e $libdir . $mysqllibrary && !-e $libdir . 'mysql/' . $mysqllibrary );
        }
    }
    return;
}

1;
