# Copyright 2020 Google LLC
#
# Licensed 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
#
#     https://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.

""" server configuration for the assetMG tool"""
import json
from math import floor
from flask import Flask, request, jsonify, render_template
from google.ads.googleads.client import GoogleAdsClient
import app.backend.setup as setup
from app.backend.mutate import mutate_ad
from app.backend import structure
from app.backend.upload_asset import upload
from app.backend.error_handling import error_mapping
from app.backend.get_yt import get_all_yt_videos
from app.backend.helpers import populate_adgroup_details
from googleapiclient.discovery import build
from pathlib import Path
import copy
import logging
import yaml
from google_auth_oauthlib.flow import InstalledAppFlow, Flow
import webbrowser
import threading
import os
import shutil
from werkzeug.utils import secure_filename
import string
from google.cloud import storage
from app.backend.setup import CONFIG_PATH, CONFIG_PATH_GS, PREFIX, CLOUD_VERSION, BASE_URL, BUCKET_NAME, YT_CONFIG
from app.backend.setup import YT_CONFIG_FILE_PATH, YT_CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH,CONFIG_FILE_PATH_GS

# from flask_cors import CORS
# app = Flask(__name__)
# CORS(app)

app = Flask(__name__, static_url_path='',
            static_folder='app/asset_browser/frontend/dist/frontend',
            template_folder='app/asset_browser/frontend/dist/frontend')



UPLOAD_FOLDER = Path(PREFIX + 'uploads')
UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)


ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'zip'}
# A list of allowed image ratios and their repectavie minimum sizes
ALLOWED_RATIOS = [[(1,1),(200,200)], [(4,5),(320,400)], [(1.91,1),(600,314)]]

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

#Only used in local version
LOGS_PATH = Path('app/logs/server.log')

YT_CLIENT_SCOPES = ['https://www.googleapis.com/auth/youtube.upload']

Path(PREFIX + 'cache').mkdir(parents=True, exist_ok=True)

if CLOUD_VERSION:
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s:%(levelname)s:%(message)s')
else:
    logging.basicConfig(filename=LOGS_PATH,
                        level=logging.INFO,
                        format='%(asctime)s:%(levelname)s:%(message)s')


flow = None
ADWORDS_CLIENT = ''
GOOGLEADS_CLIENT = ''

def get_global_googleads_client():
    global GOOGLEADS_CLIENT
    if GOOGLEADS_CLIENT:
        return GOOGLEADS_CLIENT
    else:
        setup.set_api_configs()
        GOOGLEADS_CLIENT = GoogleAdsClient.load_from_storage(
            CONFIG_PATH / 'google-ads.yaml')
        return GOOGLEADS_CLIENT

# check if config is valid. if yes, init clients and create struct
try:
    # Copy Google Storage file to tmp file
    setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH)
    with open(CONFIG_FILE_PATH, 'r') as f:
        config_file = yaml.load(f, Loader=yaml.FullLoader)
except FileNotFoundError:
    config_file = {'config_valid': 0}


@app.route('/')
def upload_frontend():
    return render_template('index.html')


@app.route('/config/', methods=['GET'])
def get_configs():
    """return all config parameters"""
    try:
        setup.download_file_from_gcs(CONFIG_FILE_PATH_GS, CONFIG_FILE_PATH)
        with open(CONFIG_FILE_PATH, 'r') as fi:
            config = yaml.load(fi, Loader=yaml.FullLoader)
    except FileNotFoundError:
        config = {
            'client_customer_id': '',
            'client_id': '',
            'client_secret': '',
            'developer_token': '',
            'refresh_token': '',
            'config_valid': 0,
        }
    return _build_response(json.dumps(config))


@app.route('/set-configs/', methods=['POST'])
def set_secret():
    """gets client id, client secret, dev token, account id.
    Saves to config.yaml and returns refresh url"""
    data = request.get_json(force=True)

    # determines if a reset to prev valid config or trying to setup new config
    is_reset = True

    if not data.get('config_valid'):
        data['refresh_token'] = None
        data['config_valid'] = 0
        is_reset = False

    with open(CONFIG_FILE_PATH, 'w') as fi:
        yaml.dump(data, fi)