package yifangcloud;
use Crypt::JWT qw(encode_jwt);
use Encode;
use IO::File;
use JSON;
use LWP::UserAgent;
use MIME::Base64;
our @EXPORT = qw/ get_user randstr token /;

my $conf_file = "conf.json";
my $rsa_file = "rsa_private_key.pem";
my $user_file = "ypusers.json";
my $token_url = "https://oauth.fangcloud.com/oauth/token";
my $admin_url = "https://open.fangcloud.com/api/v2/admin";

=get_department
get_department(HASH)
=cut

sub get_department {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        my $dp_id = $json->{did} || 0;
        my $reply;
        my $ua = LWP::UserAgent->new;
        $ua->timeout(10);
        $ua->env_proxy;
        my $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
        $res = $ua->get("$admin_url/department/$dp_id/children");
        if ( $res->is_success ) {
            $reply->{status} = 0;
        }
        else {
            $reply->{status} = $res->status_line;
        }
        $reply->{content} = decode_json($res->decoded_content);
        return $reply;
    }
}

=get_group
get_group(HASH)
=cut

sub get_group {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        my $reply;
        my $ua = LWP::UserAgent->new;
        $ua->timeout(10);
        $ua->env_proxy;
        my $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
        $res = $ua->get("$admin_url/group/list");
        if ( $res->is_success ) {
            $reply->{status} = 0;
        }
        else {
            $reply->{status} = $res->status_line;
        }
        $reply->{content} = decode_json($res->decoded_content);
        return $reply;
    }
}

=get_group_users
get_group_users(HASH)
=cut

sub get_group_users {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        my $dp_id = $json->{gid} || 0;
        my $reply;
        my $ua = LWP::UserAgent->new;
        $ua->timeout(10);
        $ua->env_proxy;
        my $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
        $res = $ua->get("$admin_url/group/$dp_id/users");
        if ( $res->is_success ) {
            $reply->{status} = 0;
        }
        else {
            $reply->{status} = $res->status_line;
        }
        $reply->{content} = decode_json($res->decoded_content);
        return $reply;
    }
}

=get_user
get_user(HASH)
=cut

sub get_user {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        my $count = 1;
        my $page_id = 0;
        my $dp_id = $json->{cid} || 0;
        my $reply;
        my $users = [];
        my $fh = new IO::File $user_file, "r";
        if ( defined $fh ) {
            $users = from_json(<$fh>);
            undef $fh;
        }
        my $ua = LWP::UserAgent->new;
        $ua->timeout(10);
        $ua->env_proxy;
        my $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
        while ( $page_id < $count ) {
            $res = $ua->get("$admin_url/department/$dp_id/users?page_id=$page_id");
            if ( $res->is_success ) {
                $reply->{status} = 0;
                my $temp = decode_json($res->decoded_content);
                if ( $temp->{total_count} == $#{$users} + 1 ) {
                    $reply->{content}->{users} = $users;
                    $reply->{content}->{total_count} = $temp->{total_count};
                    return $reply;
                }
                if ( $page_id ) {
                    $reply->{content}->{users} = [@{$reply->{content}->{users}},@{$temp->{users}}];
                }
                else {
                    $reply->{content} = $temp;
                    $count = $reply->{content}->{page_count};
                }
            }
            else {
                $reply->{status} = $res->status_line;
                $reply->{content} = decode_json($res->decoded_content);
            }
            $page_id++;
        }
        unless ( $dp_id ) {
            $fh = new IO::File $user_file, "w";
            if ( defined $fh ) {
                $users = encode_json($reply->{content}->{users});
                print $fh $users;
                undef $fh;
            }
        }
        return $reply;
    }
}

=randstr
randstr(INT)
=cut

sub randstr {
    if ( @_ ) {
        my $i = $_[0];
        if ( $i =~ /^\d+$/ ) {
            my @charset = (0..9,'a'..'z','A'..'Z');
            my $str = join '', map{$charset[int rand @charset]} 0..$i;
            return $str;
        }
    }
}

=search
search(HASH)
=cut

sub search {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        $ua = LWP::UserAgent->new;
        $ua->timeout(10);
        $ua->env_proxy;
        $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
        $res = $ua->get("$admin_url/user/$json->{uid}/info");
        my $reply;
        if ( $res->is_success ) {
            $reply->{status} = 0;
        }
        else {
            $reply->{status} = $res->status_line;
        }
        $reply->{content} = decode_json($res->decoded_content);
        return $reply;
    }
}

=token
token()
=cut

sub token() {
    my $fh = new IO::File $conf_file, "r";
    if ( defined $fh ) {
        my $json = join('',<$fh>);
        $json =~ s/\s//g;
        my $conf = from_json($json);
        undef $fh;
        $fh = new IO::File $rsa_file, "r";
        if ( defined $fh ) {
            my $pem_key_string = join('',<$fh>);
            undef $fh;
            $conf->{claims}->{exp} = time() + 30;
            $conf->{claims}->{jti} = randstr(10) . randstr(10);
            my $encrypt = encode_base64($conf->{client}->{id} . ":" . $conf->{client}->{secret});
            my $token = encode_jwt(payload => encode_json($conf->{claims}),
                                   alg => $conf->{header}->{alg},
                                   key => \$pem_key_string,
                                   extra_headers => {kid => $conf->{header}->{kid}});
            my $ua = LWP::UserAgent->new;
            $ua->timeout(10);
            $ua->env_proxy;
            my $res = $ua->default_header(Authorization => "Basic $encrypt");
            $res = $ua->post("$token_url?grant_type=jwt&assertion=$token");
            my $reply;
            if ( $res->is_success ) {
                $reply->{status} = 0;
            }
            else {
                $reply->{status} = $res->status_line;
            }
            $reply->{content} = decode_json($res->decoded_content);
            return $reply;
        }
    }
}

=user_create
user_create(HASH)
=cut

sub user_create {
    if ( @_ && ref $_[0] eq 'HASH' ) {
        my $json = $_[0];
        if ( $json->{users}->[0]->{id} =~ /^\d+$/ ) {
            my $data;
            $data->{users} = $json->{users};
            $ua = LWP::UserAgent->new;
            $ua->timeout(10);
            $ua->env_proxy;
            $res = $ua->default_header(Authorization => "$json->{token_type} $json->{access_token}",);
            $res = $ua->post("$admin_url/platform/20/sync_users",Content => encode_json($data),Content_type =>'application/json');
            my $reply;
            if ( $res->is_success ) {
                $reply->{status} = 0;
            }
            else {
                $reply->{status} = $res->status_line;
            }
            $reply->{content} = decode_json($res->decoded_content);
            return $reply;
        }
    }
}

=encoding utf8

= cut

1;
__END__