#!/usr/bin/env perl

use strict;
use warnings;

use Getopt::Std qw(getopts);

my %opts;
getopts("dm:", \%opts) or usage();

my $mode = $opts{m};

if ($opts{d}) {
    shell("mkdir -p @ARGV");
    exit;
}

if (@ARGV < 2) {
    usage();
}

my $dst = pop;

my @src = @ARGV;

my $target_dir;

if (@src > 1 || $dst =~ m{/$}) {
    $target_dir = $dst;

} elsif (-d $dst) {
    $target_dir = $dst;

} elsif ($dst =~ m{(.+)/}) {
    $target_dir = $1;

} else {
    $target_dir = '.';
}

if (!-d $target_dir) {
    shell("mkdir -p $target_dir");
}

if (-f $dst) {
    shell("rm $dst");

} else {
    for my $f (@src) {
        if (-f $f) {
            (my $name = $f) =~ s{.*/}{}g;
            my $target = "$target_dir/$name";
            if (-f $target) {
                shell("rm $target");
            }
        }
    }
}

shell("cp @src $dst");

if (-f $dst) {
    if (defined $mode) {
        chmod oct($mode), $dst or
            die "failed to change mode of $dst to $mode.\n";
    }

    exit;
}

for my $src (@src) {
    my $name;

    if ($src =~ m{/([^/]+)$}) {
        $name = $1;

    } else {
        $name = $src;
    }

    if (defined $mode) {
        my $target = "$target_dir/$name";
        chmod oct($mode), $target or
            die "failed to change mode of $target to $mode.\n";
    }
}

sub usage {
    die "Usage: install [-d] [-m <attrs>] <src>... <dst>\n";
}

sub shell {
    my $cmd = shift;
    #warn $cmd;
    system($cmd) == 0 or
        die "failed to run command $cmd\n";
}