#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4
#
# Copyright (C) 2017 Samsung Electronics. Co,. Ltd.
#
#    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; version 2
#    of the License.
#
#    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.
#
"""
Interface of Tizen Studio
"""

import os
import sys
import shutil
import re
import stat
import ast
import subprocess
import glob
from datetime import datetime
from random import randint

sys.path.insert(1, os.path.join(sys.path[0], '..'))

from common.utils import wget_noproxy, list_files_in_url, tail
from common.buildtrigger import trigger_info, trigger_next
from common.git import Git, clone_gitproject
from common.gerrit import GerritEnv

class LocalError(Exception):
    """Local error exception."""
    pass

class TizenStudio(object):

    def __init__(self, baseDir=None, confData=None):

        if baseDir is not None:
            self.basedir = baseDir
        else:
            self.basedir = os.path.join(os.getenv('WORKSPACE'), os.getenv('JOB_NAME'))
        self.builddir = os.path.join(self.basedir, 'build')

        if confData is not None:
            self.confData = confData

        self.build_root = '/home/build'
        self.share_root = '/share/build'

        # Fetch ABS cli wrapper from gerrit
        self.wrapper_path = self.fetch_resources(confData.get('ABS_CLI_SCRIPT_GIT').split(','))
        print 'wrapper_path:%s' % self.wrapper_path

        self.sdk_path = os.path.join(self.build_root, 'tizen-sdk-cli')

    def get_template(self, mode=None):

        with open(os.path.join(self.wrapper_path, '%s.template' % mode), 'r') as rf:
            cmd_template = rf.read()
        return cmd_template

    def run_tizen_studio(self, cmd_to_run):

        with open(os.path.join(self.builddir, 'run'), 'w') as fcmdl:
            fcmdl.write('%s' % cmd_to_run)
        os.chmod(os.path.join(self.builddir, 'run'), 0o777)

        if True:
            print 'DOCKER running...'
            cmd = os.path.join(self.builddir, 'run')
            print 'Running inside docker [%s]' % cmd
    
        scr = subprocess.call(cmd, stdout=sys.stdout,
                              stderr=sys.stderr, shell=True)
    
        #read testresult from file
        return int(scr)

    def fetch_resources(self, rc_repo_branch=[]):

        rc_git_path, rc_git_branch = rc_repo_branch
        print 'fetch_resources: [%s] [%s]' % (rc_git_path, rc_git_branch)
        rc_dir = os.path.join(self.share_root, os.path.basename(rc_git_path))
        print 'rc_dir:%s' % rc_dir
        if not clone_gitproject(rc_git_path, rc_dir):
            print 'Error clone project %s' % rc_git_path 
        rc_git = Git(rc_dir)
        rc_git.checkout(rc_git_branch)
        return rc_git.path

    def update_rootstrap(self, rootstrap_src_url, rootstrap_version, profiles=[]):

        # Fetch sdk-tool from gerrit
        sdk_tool_path = self.fetch_resources(self.confData.get('SDK_TOOL_GIT').split(','))
        print 'sdk_tool_path:%s' % sdk_tool_path

        # Fetch hash-sign package from gerrit
        hash_sign_path = self.fetch_resources(self.confData.get('SDK_SIGN_GIT').split(','))
        print 'hash_sign_path:%s' % hash_sign_path
        certificate_path = hash_sign_path
        author_cert_path = self.confData.get('SDK_SIGN_AUTHOR').split(',')[0]
        author_cert_pass = self.confData.get('SDK_SIGN_AUTHOR').split(',')[1]
        dist_cert_path   = self.confData.get('SDK_SIGN_DIST').split(',')[0]
        dist_cert_pass   = self.confData.get('SDK_SIGN_DIST').split(',')[1]

        update_cmd = self.get_template('update')
        update_cmd = update_cmd.replace( \
                     '__SDK_PATH__',           self.sdk_path).replace( \
                     '__SHARE_ROOT__',         self.share_root).replace( \
                     '__TOOL_PATH__',          os.path.join(self.share_root, os.path.basename(sdk_tool_path))).replace( \
                     '__WRAPPER_PATH__',       os.path.join(self.share_root, os.path.basename(self.wrapper_path))).replace( \
                     '__PROFILE__',            ' '.join(profiles)).replace( \
                     '__PACKAGE_SERVER__',     os.getenv('ABS_SDK_PACKAGE_SERVER')).replace( \
                     '__ROOTSTRAP_URL__',      rootstrap_src_url).replace( \
                     '__CERTIFICATE_PATH__',   certificate_path).replace( \
                     '__AUTHOR_CERTIFICATE__', author_cert_path).replace( \
                     '__AUTHOR_PASSWORD__',    author_cert_pass).replace( \
                     '__DIST_CERTIFICATE__',   dist_cert_path).replace( \
                     '__DIST_PASSWORD__',      dist_cert_pass)

        update_cmd = update_cmd.replace('su - build -c', 'sudo su - build -c')
        print 'UPDATE_CMD:\n%s' % update_cmd

        #### Running QEMU to launch Tizen Studio ####
        print '[ TizenStudio START ] %s' % (str(datetime.now()))
        sys.stdout.flush()
        ret = self.run_tizen_studio(update_cmd)
        print '[ TizenStudio END ] %s' % (str(datetime.now()))

    def gather_build_result(self):

        # Get installed rootstrap version
        built_version = None
        with open(os.path.join(self.builddir, 'rsver')) as rsverfile:
            built_version = rsverfile.read().replace(' ', ', ').replace('\n', ' ').encode('utf8')
            built_version = built_version.split('.')[-1]
            print 'Installed RS version... %s' % built_version
        if built_version is None:
            print 'Not able detect installed Rootstrap version'

        tizen_studio_version = 'Tizen CLI 0.0.0'
        tizen_studio_distribution = 'default'
        with open(os.path.join(self.builddir, 'tizen_studio_version')) as tizenstudioverfile:
            tizen_studio_version = tizenstudioverfile.read().strip()
            print 'Installed Tizen Studio version... %s' % tizen_studio_version
        with open(os.path.join(self.builddir, 'tizen_studio_distribution')) as tizenstudiodistributionfile:
            tizen_studio_distribution = tizenstudiodistributionfile.read().strip()
            print 'Installed Tizen Studio Distribution... %s' % tizen_studio_distribution

        self.built_version = built_version
        self.tizen_studio_version = tizen_studio_version
        self.tizen_studio_distribution = tizen_studio_distribution

        # Get building log
        self.buildlog = ''
        mtime = lambda f: os.stat(os.path.join(self.builddir, f)).st_mtime
        for filename in list(sorted(os.listdir(self.builddir), key=mtime)):
            if re.match('build.*\.log', filename):
                onefile = tail(os.path.join(self.builddir, filename), c=4096)
                self.buildlog = onefile[:onefile.rfind("Finished build-native")]

        if self.build_result != 0:
            return {'built_version': built_version, \
                    'title': 'FAIL::CLI BUILD', \
                    'buildlog': self.buildlog, \
                    'tizen_studio_version': tizen_studio_version, \
                    'tizen_studio_distribution': tizen_studio_distribution}

        # Get packaging log
        sys.stdout.flush()
        print glob.glob(os.path.join(self.builddir, '*.tpk'))
        print glob.glob(os.path.join(self.builddir, '*.wgt'))
        print os.listdir(self.builddir)
        sys.stdout.flush()
        if not glob.glob(os.path.join(self.builddir, '*.tpk')) and not glob.glob(os.path.join(self.builddir, '*.wgt')):
            for filename in os.listdir(self.builddir):
                if re.match('pkg.*\.log', filename):
                    self.buildlog = self.buildlog + tail(os.path.join(self.builddir, filename))
            return {'built_version': built_version, \
                    'title': 'FAIL::CLI PKG', \
                    'buildlog': self.buildlog, \
                    'tizen_studio_version': tizen_studio_version, \
                    'tizen_studio_distribution': tizen_studio_distribution}

        return {'built_version': built_version, \
                'title': None, \
                'buildlog': None, \
                'tizen_studio_version': tizen_studio_version, \
                'tizen_studio_distribution': tizen_studio_distribution}

    def build_app_source(self, package, profile=None, gitpath=None, build_mode='Release', parallel_jobs='', build_type='default'):

        PROFILE = profile

        build_cmd = self.get_template('build')
        print 'build_mode:%s' % build_mode
        print 'package:%s' % package
        print 'parrel_jobs:%s' % parallel_jobs
        print 'profile:%s' % PROFILE
        print 'sdk_path:%s' % self.sdk_path
        print 'share_root:%s' % self.share_root
        print 'build_root:%s' % self.build_root
        build_cmd = build_cmd.replace( \
                     '__SDK_PATH__', self.sdk_path).replace( \
                     '__SHARE_ROOT__', self.share_root).replace( \
                     '__BUILD_ROOT__', self.build_root).replace( \
                     '__PROFILE__', PROFILE).replace( \
                     '__PACKAGE__', package).replace( \
                     '__PARALLEL_JOBS__', parallel_jobs).replace( \
                     '__BUILD_MODE__', build_mode).replace( \
                     '__BUILD_TYPE__', build_type)

        build_cmd = build_cmd.replace('su - build -c', 'sudo su - build -c')
        print 'BUILD_CMD:\n%s' % build_cmd

        #### Running QEMU to launch Tizen Studio ####
        print '[ TizenStudio START ] %s' % (str(datetime.now()))
        sys.stdout.flush()
        ret = self.run_tizen_studio(build_cmd)
        print '[ TizenStudio END ] %s' % (str(datetime.now()))

        self.build_result = int(ret)
        return self.build_result

if __name__ == '__main__':
    print 'This is not callable module'
    sys.exit(-1)

