#! /usr/bin/perl

# $Id: ctags-direct.sh 34 2010-05-11 06:25:18Z lena-san $

use strict;
use warnings;

=head1 NAME

    direct-ctags

=head1 SYNOPSIS

    direct-ctags

=head1 DESCRIPTION

    ctags для Директа 
    запускать из корневого каталога беты

    собираются: 
    + обычные теги для perl и javascript-файлов
    + для функций типа "cmd_doSmth" добавляются теги без префикса "cmd_" (для переходов с redirect("?cmd=doSmth"); )
    + добавляются js-функции в html-файлах
    + добавляются теги для имен файлов: .html, .tt2, .pl и т.д.
    + теги для TT-макросов

    TODO 

=head1 comments

=cut

use Getopt::Long;
use File::Find;
use File::Slurp;
use List::MoreUtils qw(uniq);


GetOptions (
    "h|help"            => \&usage,
) or die "Can't parse options";


# основа
my @tagsunsorted = qx!ctags -f - --languages=Perl,JavaScript --totals -R '--exclude=*.pl' '--exclude=data/lego/*' '--exclude=data/block/*' '--exclude=data/js-c/*' '--exclude=data/js/jquery-check.js' '--exclude=_*.js' --regex-perl='/\\s*method\\s+([-a-zA-Z0-9_]+)\\s*\\(/\\1/'!;

# теги по именам файлов (и с расширением, и без него)
find(
    sub {
        return if $File::Find::name =~ /\.svn/;
        return if $File::Find::name !~ /.(pl|html|tt2|js)$/; # css не надо, наверное
        return if $File::Find::name =~ m!(data/t/seminar|data/lego)!;
        (my $name = $_) =~ s/\.[^\.]+$//;
        push @tagsunsorted, qq!$name\t$File::Find::name\t1;"\tF\n!;
        push @tagsunsorted, qq!$_\t$File::Find::name\t1;"\tF\n!;
    },
   'data', 'protected'
);

# find all templates and javascripts
# find all js funtions in html
my @html_files;
find (
    sub {
        return if $File::Find::name =~ /\.svn/;
        return if $File::Find::name !~ /.(html|tt2)$/; 
        push @html_files, $File::Find::name;
    },
    'data/t'
);
my $html_files_str = join ' ', @html_files;
my @js_functions_from_html = qx!ctags -f - --language-force=JavaScript $html_files_str!;
push @tagsunsorted, grep { !/^_TAG_/ } @js_functions_from_html;

# макросы из TT-шаблонов
my @tempalte_files;
find (
    sub {
        return if $File::Find::name =~ /\.svn/;
        return if $File::Find::name !~ /.(html|tt2)$/; 

        my @lines = read_file($_);
        for my $line (@lines){
            my ( $str, $macro ) = $line =~ /\[%[\-~]?\s+(MACRO\s+([_a-zA-Z0-9]+))\W/;
            next unless $str;
            push @tagsunsorted, "$macro\t$File::Find::name\t/$str/\n";
        }
    },
    'data/t', 'data/block'
);

# методы из js-объектов
#egrep '^this\.' tagsunsorted | sed 's/^this\.//' >> tagsunsorted

# find all cmds
for my $tag (@tagsunsorted){
    (my $cmd_tag = $tag) =~ s/^cmd_//;
    push @tagsunsorted, $cmd_tag if $cmd_tag ne $tag;
}

@tagsunsorted = uniq sort grep { !/^.{300,}/ } @tagsunsorted; 

write_file('tags', @tagsunsorted);

exit;



# Печатает usage-сообщение
sub usage {
    system("podselect -section SYNOPSIS -section DESCRIPTION $0 | pod2text-utf8 >&2");
    exit(0);
}

