// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use {
    failure::{Error, ResultExt},
    fidl_fuchsia_io::DirectoryProxy,
    fidl_fuchsia_pkg::PackageCacheMarker,
    fuchsia_async as fasync,
    fuchsia_component::client::connect_to_service,
    fuchsia_component::server::ServiceFs,
    fuchsia_inspect as inspect,
    fuchsia_syslog::{self, fx_log_err, fx_log_info},
    futures::{StreamExt, TryFutureExt},
    parking_lot::RwLock,
    std::{io, sync::Arc},
    sysconfig_client,
};

mod amber_connector;
mod cache;
mod config;
mod experiment;
mod font_package_manager;
mod repository_manager;
mod repository_service;
mod resolver_service;
mod rewrite_manager;
mod rewrite_service;

#[cfg(test)]
mod test_util;

#[allow(dead_code)]
mod queue;

use crate::amber_connector::AmberConnector;
use crate::cache::PackageCache;
use crate::experiment::Experiments;
use crate::font_package_manager::{FontPackageManager, FontPackageManagerBuilder};
use crate::repository_manager::{RepositoryManager, RepositoryManagerBuilder};
use crate::repository_service::RepositoryService;
use crate::rewrite_manager::{RewriteManager, RewriteManagerBuilder};
use crate::rewrite_service::RewriteService;

const SERVER_THREADS: usize = 2;

const STATIC_REPO_DIR: &str = "/config/data/repositories";
const DYNAMIC_REPO_PATH: &str = "/data/repositories.json";

const STATIC_RULES_PATH: &str = "/config/data/rewrites.json";
const DYNAMIC_RULES_PATH: &str = "/data/rewrites.json";

const STATIC_FONT_REGISTRY_PATH: &str = "/config/data/font_packages.json";

fn main() -> Result<(), Error> {
    fuchsia_syslog::init_with_tags(&["pkg_resolver"]).expect("can't init logger");
    fx_log_info!("starting package resolver");

    let mut executor = fasync::Executor::new().context("error creating executor")?;

    let config = config::Config::load_from_config_data_or_default();

    let pkg_cache =
        connect_to_service::<PackageCacheMarker>().context("error connecting to package cache")?;
    let pkgfs_install = connect_to_pkgfs("install").context("error connecting to pkgfs/install")?;
    let pkgfs_needs = connect_to_pkgfs("needs").context("error connecting to pkgfs/needs")?;
    let cache = PackageCache::new(pkg_cache, pkgfs_install, pkgfs_needs);

    let inspector = fuchsia_inspect::Inspector::new();
    let rewrite_inspect_node = inspector.root().create_child("rewrite_manager");
    let experiment_inspect_node = inspector.root().create_child("experiments");

    let amber_connector = AmberConnector::new();

    let experiment_state = Arc::new(RwLock::new(experiment::State::new(experiment_inspect_node)));
    let experiments = Arc::clone(&experiment_state).into();

    let font_package_manager = Arc::new(load_font_package_manager());
    let repo_manager = Arc::new(RwLock::new(load_repo_manager(amber_connector, experiments)));
    let rewrite_manager = Arc::new(RwLock::new(load_rewrite_manager(
        rewrite_inspect_node,
        &repo_manager.read(),
        config.disable_dynamic_configuration(),
    )));

    let resolver_cb = {
        // Capture a clone of repo and rewrite manager's Arc so the new client callback has a copy
        // from which to make new clones.
        let repo_manager = Arc::clone(&repo_manager);
        let rewrite_manager = Arc::clone(&rewrite_manager);
        let cache = cache.clone();
        move |stream| {
            fasync::spawn(
                resolver_service::run_resolver_service(
                    Arc::clone(&rewrite_manager),
                    Arc::clone(&repo_manager),
                    cache.clone(),
                    stream,
                )
                .unwrap_or_else(|e| fx_log_err!("failed to spawn {:?}", e)),
            )
        }
    };

    let font_resolver_fb = {
        let repo_manager = Arc::clone(&repo_manager);
        let rewrite_manager = Arc::clone(&rewrite_manager);
        let cache = cache.clone();
        move |stream| {
            fasync::spawn(
                resolver_service::run_font_resolver_service(
                    Arc::clone(&font_package_manager),
                    Arc::clone(&rewrite_manager),
                    Arc::clone(&repo_manager),
                    cache.clone(),
                    stream,
                )
                .unwrap_or_else(|e| fx_log_err!("Failed to spawn font_resolver_service {:?}", e)),
            )
        }
    };

    let repo_cb = move |stream| {
        let repo_manager = Arc::clone(&repo_manager);

        fasync::spawn(
            async move {
                let mut repo_service = RepositoryService::new(repo_manager);
                repo_service.run(stream).await
            }
                .unwrap_or_else(|e| fx_log_err!("error encountered: {:?}", e)),
        )
    };

    let rewrite_cb = move |stream| {
        let mut rewrite_service = RewriteService::new(Arc::clone(&rewrite_manager));

        fasync::spawn(
            async move { rewrite_service.handle_client(stream).await }
                .unwrap_or_else(|e| fx_log_err!("while handling rewrite client {:?}", e)),
        )
    };

    let admin_cb = move |stream| {
        let experiment_state = Arc::clone(&experiment_state);
        fasync::spawn(async move {
            experiment::run_admin_service(experiment_state, stream)
                .await
                .unwrap_or_else(|e| fx_log_err!("while handling admin client {:?}", e))
        });
    };

    let mut fs = ServiceFs::new();
    fs.dir("svc")
        .add_fidl_service(resolver_cb)
        .add_fidl_service(font_resolver_fb)
        .add_fidl_service(repo_cb)
        .add_fidl_service(rewrite_cb)
        .add_fidl_service(admin_cb);

    inspector.export(&mut fs);

    fs.take_and_serve_directory_handle()?;

    let () = executor.run(fs.collect(), SERVER_THREADS);

    Ok(())
}

fn connect_to_pkgfs(subdir: &str) -> Result<DirectoryProxy, Error> {
    io_util::open_directory_in_namespace(
        &format!("/pkgfs/{}", subdir),
        io_util::OPEN_RIGHT_READABLE | io_util::OPEN_RIGHT_WRITABLE,
    )
}

fn load_repo_manager(
    amber_connector: AmberConnector,
    experiments: Experiments,
) -> RepositoryManager<AmberConnector> {
    // report any errors we saw, but don't error out because otherwise we won't be able
    // to update the system.
    RepositoryManagerBuilder::new(DYNAMIC_REPO_PATH, amber_connector, experiments)
        .unwrap_or_else(|(builder, err)| {
            fx_log_err!("error loading dynamic repo config: {}", err);
            builder
        })
        .load_static_configs_dir(STATIC_REPO_DIR)
        .unwrap_or_else(|(builder, errs)| {
            for err in errs {
                match err {
                    crate::repository_manager::LoadError::Io { path: _, error }
                        if error.kind() == io::ErrorKind::NotFound =>
                    {
                        fx_log_info!("no statically configured repositories present");
                    }
                    _ => fx_log_err!("error loading static repo config: {}", err),
                };
            }
            builder
        })
        .build()
}

fn load_rewrite_manager(
    node: inspect::Node,
    repo_manager: &RepositoryManager<AmberConnector>,
    disable_dynamic_configuration: bool,
) -> RewriteManager {
    let dynamic_rules_path =
        if disable_dynamic_configuration { None } else { Some(DYNAMIC_RULES_PATH) };
    let builder = RewriteManagerBuilder::new(dynamic_rules_path)
        .unwrap_or_else(|(builder, err)| {
            if err.kind() != io::ErrorKind::NotFound {
                fx_log_err!(
                    "unable to load dynamic rewrite rules from disk, using defaults: {}",
                    err
                );
            }
            builder
        })
        .inspect_node(node)
        .static_rules_path(STATIC_RULES_PATH)
        .unwrap_or_else(|(builder, err)| {
            if err.kind() != io::ErrorKind::NotFound {
                fx_log_err!("unable to load static rewrite rules from disk: {}", err);
            }
            builder
        });

    // If we have a channel in sysconfig, we don't want to load the dynamic configs. Instead, we'll
    // construct a unique rule for that channel.
    let channel = match sysconfig_client::channel::read_channel_config() {
        Ok(channel) => channel,
        Err(err) => {
            fx_log_info!("unable to load channel from sysconfig, using defaults: {}", err);
            return builder.build();
        }
    };
    let tuf_config_name = channel.tuf_config_name();
    fx_log_info!("current TUF config name is {}", tuf_config_name);

    let repo = match repo_manager.get_repo_for_channel(tuf_config_name) {
        Some(repo) => repo,
        None => {
            fx_log_err!("unable to find repo for channel, using defaults");
            return builder.build();
        }
    };
    fx_log_info!("channel repo is {}", repo.repo_url());

    match fuchsia_url_rewrite::Rule::new("fuchsia.com", repo.repo_url().host(), "/", "/") {
        Ok(rule) => builder.replace_dynamic_rules(vec![rule]).build(),
        Err(err) => {
            fx_log_err!(
                "failed to make rewrite rule for {}, using defaults: {}",
                repo.repo_url(),
                err
            );
            builder.build()
        }
    }
}

fn load_font_package_manager() -> FontPackageManager {
    FontPackageManagerBuilder::new()
        .add_registry_file(STATIC_FONT_REGISTRY_PATH)
        .unwrap_or_else(|(builder, errs)| {
            let errors = errs
                .iter()
                .filter(|err| {
                    if err.is_not_found() {
                        fx_log_info!("no font package registry present");
                        false
                    } else {
                        true
                    }
                })
                .fold(String::new(), |acc, err| acc + "\n" + format!("{}", err).as_str());
            if !errors.is_empty() {
                fx_log_err!("error(s) loading font package registry:{}", errors);
            }
            builder
        })
        .build()
}
