#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

import logging
import sys

from ming.orm import ThreadLocalORMSession
from pylons import tmpl_context as c, app_globals as g

from allura import model as M
from allura.lib import helpers as h
from allura.lib import utils

log = logging.getLogger(__name__)

def main(options):
    log.addHandler(logging.StreamHandler(sys.stdout))
    log.setLevel(getattr(logging, options.log_level.upper()))

    nbhd = M.Neighborhood.query.get(name=options.neighborhood)
    if not nbhd:
        return 'Invalid neighborhood "%s".' % options.neighborhood
    admin_role = M.ProjectRole.by_name('Admin', project=nbhd.neighborhood_project)
    nbhd_admin = admin_role.users_with_role(project=nbhd.neighborhood_project)[0].user
    log.info('Making updates as neighborhood admin "%s"' % nbhd_admin.username)

    q = {'neighborhood_id': nbhd._id,
            'is_nbhd_project': False, 'deleted':False}
    private_count = public_count = 0
    for projects in utils.chunked_find(M.Project, q):
        for p in projects:
            role_anon = M.ProjectRole.upsert(name='*anonymous',
                    project_id=p.root_project._id)
            if M.ACE.allow(role_anon._id, 'read') not in p.acl:
                if options.test:
                    log.info('Would be made public: "%s"' % p.shortname)
                else:
                    log.info('Making public: "%s"' % p.shortname)
                    p.acl.append(M.ACE.allow(role_anon._id, 'read'))
                    with h.push_config(c, project=p, user=nbhd_admin):
                        ThreadLocalORMSession.flush_all()
                        g.post_event('project_updated')
                private_count += 1
            else:
                log.info('Already public: "%s"' % p.shortname)
                public_count += 1

    log.info('Already public: %s' % public_count)
    if options.test:
        log.info('Would be made public: %s' % private_count)
    else:
        log.info('Made public: %s' % private_count)
    return 0

def parse_options():
    import argparse
    parser = argparse.ArgumentParser(
            description='Make all projects in a neighborhood public.')
    parser.add_argument('neighborhood', metavar='NEIGHBORHOOD', type=str,
            help='Neighborhood name.')
    parser.add_argument('--test', dest='test', default=False,
            action='store_true',
            help='Run in test mode (no updates will be applied).')
    parser.add_argument('--log', dest='log_level', default='INFO',
            help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
    return parser.parse_args()

if __name__ == '__main__':
    sys.exit(main(parse_options()))
