#!/usr/bin/perl -w
#----------------------------------------------------------------------
# vim: ft=perl ts=2 sw=2 et:
#----------------------------------------------------------------------
#
# Copyright (C) 2012-2013 - Marco Hess <marco.hess@through-ip.com>
#
# This file is part of the "Git Repositories" panel in the
# SME Server server-manager panel to configure git repositories.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
#
#----------------------------------------------------------------------

package esmith;

use strict;
use Errno;
use File::Find;
use esmith::util;
use esmith::templates;
use esmith::GitDB;

$ENV{'PATH'} = "/bin";

#----------------------------------------------------------------------

my $event             = $ARGV [0];
my $gitRepositoryName = $ARGV [1];

die "event argument missing" 
  unless defined ($event);

die "gitRepositoryName argument missing" 
  unless defined ($gitRepositoryName);

#----------------------------------------------------------------------

my $git_db = esmith::GitDB->open_ro();

my $repository = $git_db->get($gitRepositoryName) or 
  die "Couldn't find $gitRepositoryName record in SME Server Git database\n";
  
die "'$gitRepositoryName' is not an Git repository; git-repository-modify event failed.\n"
  unless ($repository->prop('type') eq 'repository');

#----------------------------------------------------------------------
  
my %properties  = $repository->props;  
my $description = $properties{'description'};  

my $effective_pull_users       = $git_db->effective_users_list_from( $properties{'pull_groups'},  
                                                                     $properties{'pull_users'} ); 
                                                               
my $effective_push_users       = $git_db->effective_users_list_from( $properties{'push_groups'}, 
                                                                     $properties{'push_users'} ); 
                                                               
my $effective_pull_push_users  = $git_db->effective_users_list_from( $properties{'push_groups'}, 
                                                                     $properties{'push_users'}, 
                                                                     $properties{'pull_groups'},  
                                                                     $properties{'pull_users'} );
                                                               
if ($event eq 'git-repository-create')
{
  #------------------------------------------------------------
  # Create a bare git repository
  # We add the .git extension to the repository name to indicate 
  # is a bare repository. Permssions are set such that the 
  # repository is owned by admin and is accessible to the group
  # www (so Apache can access it) but not anybody else.
  #------------------------------------------------------------

  # Create the bare repository
  system("/usr/bin/git", "init", "--bare", "--shared=0660", "/home/e-smith/files/git/$gitRepositoryName.git") == 0
    or die "Error creating the initial bare git repository structure for /home/e-smith/files/git/$gitRepositoryName.git";

  # Init the Git Description 
  open(my $file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/description");
  print $file $repository->prop('description') . "\n"; 
  
  # Create a 'post-update' hook
  open($file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/hooks/post-update");
  print $file "#!/bin/sh\n" .
              "# Hook script auto generated on repository create by SME server manager. Enables automatic markdown for README.md\n" .
              "# for viewing in gitweb as README.html.\n\n" .
              "rm -f README.html\n" .
              "git cat-file -e HEAD:README.md > /dev/null 2>&1\n" .
              "if [ \$? -eq 0 ]; then\n" .
              "  git cat-file blob HEAD:README.md | perl /usr/share/markdown/Markdown.pl --html4tags > README.html\n" .
              "  chmod 0440 README.html\n" .
              "fi\n\n" .
              "# Update GIT server info as well\n" .
              "git update-server-info\n";
  close($file);
  chmod 0770, "/home/e-smith/files/git/$gitRepositoryName.git/hooks/post-update";
  
  # Set Administrator as the effective owner of the repository
  chdir "/home/e-smith/files/git/$gitRepositoryName.git"
    or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git";

  system("/usr/bin/git", "config", "--add", "gitweb.owner", "Administrator") == 0
    or die "Could not change gitweb.owner setting in /home/e-smith/files/git/$gitRepositoryName.git";

  # Create a 'post-receive-email' hook to send emails when PUSH actions occur
  system("/bin/ln", "-sf", "/usr/share/git-core/contrib/hooks/post-receive-email", "hooks/post-receive") == 0
    or die "Could not link 'post-receive-email' hook in /home/e-smith/files/git/$gitRepositoryName.git";
    
  system("/usr/bin/git", "config", "--add", "hooks.emailprefix", "[GIT] ") == 0
    or die "Could not change hooks.emailprefix setting in /home/e-smith/files/git/$gitRepositoryName.git";
    
  # Create the email list with the effective push & pull users.
  system("/usr/bin/git", "config", "--add", "hooks.mailinglist", $effective_pull_push_users ) == 0
    or die "Could not create 'hooks.mailinglist' in /home/e-smith/files/git/$gitRepositoryName.git";
}
elsif ($event eq 'git-repository-modify')
{
  #------------------------------------------------------------
  # Modify the Git repository
  #------------------------------------------------------------
  
  # Update the Git description to match the setting in the server-manager interface
  open(my $file, '>', "/home/e-smith/files/git/$gitRepositoryName.git/description");
  print $file $repository->prop('description') . "\n"; 
  
  # Goto git repository
  chdir "/home/e-smith/files/git/$gitRepositoryName.git"
    or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git";

  # Update the email list with the effective push & pull users.
  system("/usr/bin/git", "config", "--replace-all", "hooks.mailinglist", $effective_pull_push_users ) == 0
    or die "Could not update 'hooks.mailinglist' in /home/e-smith/files/git/$gitRepositoryName.git";

  # Run a "git update-server-info" action for good measure
  system("/usr/bin/git", "update-server-info") == 0
    or die "Error running 'git-update-server-info' on repository /home/e-smith/files/git/$gitRepositoryName.git";
}

#------------------------------------------------------------
# Default for both create and modify is to fix the ownership
# to allow the webserver access to the repository
# Ensure that files created are with gid set for the www group.
#------------------------------------------------------------

chdir "/home/e-smith/files/git/$gitRepositoryName.git"
  or die "Could not chdir to /home/e-smith/files/git/$gitRepositoryName.git";

system("/bin/chown", "-R", "admin:www", "/home/e-smith/files/git/$gitRepositoryName.git") == 0
  or die "Could not change ownership of /home/e-smith/files/git/$gitRepositoryName.git";

chmod 02770, ".";

# Ensure that the git repository database is readable by the web server.
system("/bin/chmod", "644", "/home/e-smith/db/git") == 0
  or die "Could not change permissions on /home/e-smith/db/git";

# Ensure that the networks database is readable by the web server.
system("/bin/chmod", "644", "/home/e-smith/db/networks") == 0
  or die "Could not change permissions on /home/e-smith/db/networks";
